Ext.form.MessageTargets={
	'qtip':{
		mark:function(field,msg){
			field.el.addClass(field.invalidClass);
			field.el.dom.qtip=msg;
			field.el.dom.qclass='x-form-invalid-tip';
			if(Ext.QuickTips){
				Ext.QuickTips.enable();
			}
		},
		clear:function(field){
			field.el.removeClass(field.invalidClass);
			field.el.dom.qtip='';
		}
	},
	'title':{
		mark:function(field,msg){
			field.el.addClass(field.invalidClass);
			field.el.dom.title=msg;
		},
		clear:function(field){
			field.el.dom.title='';
		}
	},
	'under':{
		mark:function(field,msg){
			field.el.addClass(field.invalidClass);
			if(!field.errorEl){
				var elp=field.getErrorCt();
				if(!elp){
					field.el.dom.title=msg;
					return;
				}
				field.errorEl=elp.createChild({cls:'x-form-invalid-msg'});
				field.errorEl.setWidth(elp.getWidth(true)-20);
			}
			field.errorEl.update(msg);
			Ext.form.Field.msgFx[field.msgFx].show(field.errorEl,field);
		},
		clear:function(field){
			field.el.removeClass(field.invalidClass);
			if(field.errorEl){
				Ext.form.Field.msgFx[field.msgFx].hide(field.errorEl,field);
			}else{
				field.el.dom.title='';
			}
		}
	},
	'side':{
		mark:function(field,msg){
			field.el.addClass(field.invalidClass);
			if(!field.errorIcon){
				var elp=field.getErrorCt();
				if(!elp){
					field.el.dom.title=msg;
					return;
				}
				field.errorIcon=elp.createChild({cls:'x-form-invalid-icon'});
			}
			field.alignErrorIcon();
			field.errorIcon.dom.qtip=msg;
			field.errorIcon.dom.qclass='x-form-invalid-tip';
			field.errorIcon.show();
			field.on('resize',field.alignErrorIcon,field);
		},
		clear:function(field){
			field.el.removeClass(field.invalidClass);
			if(field.errorIcon){
				field.errorIcon.dom.qtip='';
				field.errorIcon.hide();
				field.un('resize',field.alignErrorIcon,field);
			}else{
				field.el.dom.title='';
			}
		}
	}};
Ext.form.Field.msgFx={
	normal:{
		show:function(msgEl,f){
			msgEl.setDisplayed('block');
		},
		hide:function(msgEl,f){
			msgEl.setDisplayed(false).update('');
		}
	},
	slide:{
		show:function(msgEl,f){
			msgEl.slideIn('t',{stopFx:true});
		},
		hide:function(msgEl,f){
			msgEl.slideOut('t',{stopFx:true,useDisplay:true});
		}
	},
	slideRight:{
		show:function(msgEl,f){
			msgEl.fixDisplay();
			msgEl.alignTo(f.el,'tl-tr');
			msgEl.slideIn('l',{stopFx:true});
		},
		hide:function(msgEl,f){
			msgEl.slideOut('l',{stopFx:true,useDisplay:true});
		}
	}};
Ext.reg('field',Ext.form.Field);
Ext.form.TextField=Ext.extend(Ext.form.Field,{
	grow:false,
	growMin:30,
	growMax:800,
	vtype:null,
	maskRe:null,
	disableKeyFilter:false,
	allowBlank:true,
	minLength:0,
	maxLength:Number.MAX_VALUE,
	minLengthText:'The minimum length for this field is {0}',
	maxLengthText:'The maximum length for this field is {0}',
	selectOnFocus:false,
	blankText:'This field is required',
	validator:null,
	regex:null,
	regexText:'',
	emptyText:null,
	emptyClass:'x-form-empty-field',
	initComponent:function(){
		Ext.form.TextField.superclass.initComponent.call(this);
		this.addEvents(
			'autosize',
			'keydown',
			'keyup',
			'keypress'
		);
	},
	initEvents:function(){
		Ext.form.TextField.superclass.initEvents.call(this);
		if(this.validationEvent=='keyup'){
			this.validationTask=new Ext.util.DelayedTask(this.validate,this);
			this.mon(this.el,'keyup',this.filterValidation,this);
		}
		else if(this.validationEvent!==false){
			this.mon(this.el,this.validationEvent,this.validate,this,{buffer:this.validationDelay});
		}
		if(this.selectOnFocus||this.emptyText){
			this.on('focus',this.preFocus,this);
			this.mon(this.el,'mousedown',function(){
				if(!this.hasFocus){
					this.el.on('mouseup',function(e){
						e.preventDefault();
					},this,{single:true});
				}
			},this);
			if(this.emptyText){
				this.on('blur',this.postBlur,this);
				this.applyEmptyText();
			}
		}
		if(this.maskRe||(this.vtype&&this.disableKeyFilter!==true&&(this.maskRe=Ext.form.VTypes[this.vtype+'Mask']))){
			this.mon(this.el,'keypress',this.filterKeys,this);
		}
		if(this.grow){
			this.mon(this.el,'keyup',this.onKeyUpBuffered,this,{buffer:50});
			this.mon(this.el,'click',this.autoSize,this);
		}
		if(this.enableKeyEvents){
			this.mon(this.el,'keyup',this.onKeyUp,this);
			this.mon(this.el,'keydown',this.onKeyDown,this);
			this.mon(this.el,'keypress',this.onKeyPress,this);
		}
	},
	processValue:function(value){
		if(this.stripCharsRe){
			var newValue=value.replace(this.stripCharsRe,'');
			if(newValue!==value){
				this.setRawValue(newValue);
				return newValue;
			}
		}
		return value;
	},
	filterValidation:function(e){
		if(!e.isNavKeyPress()){
			this.validationTask.delay(this.validationDelay);
		}
	},
	onDisable:function(){
		Ext.form.TextField.superclass.onDisable.call(this);
		if(Ext.isIE){
			this.el.dom.unselectable='on';
		}
	},
	onEnable:function(){
		Ext.form.TextField.superclass.onEnable.call(this);
		if(Ext.isIE){
			this.el.dom.unselectable='';
		}
	},
	onKeyUpBuffered:function(e){
		if(!e.isNavKeyPress()){
			this.autoSize();
		}
	},
	onKeyUp:function(e){
		this.fireEvent('keyup',this,e);
	},
	onKeyDown:function(e){
		this.fireEvent('keydown',this,e);
	},
	onKeyPress:function(e){
		this.fireEvent('keypress',this,e);
	},
	reset:function(){
		Ext.form.TextField.superclass.reset.call(this);
		this.applyEmptyText();
	},
	applyEmptyText:function(){
		if(this.rendered&&this.emptyText&&this.getRawValue().length<1&&!this.hasFocus){
			this.setRawValue(this.emptyText);
			this.el.addClass(this.emptyClass);
		}
	},
	preFocus:function(){
		var el=this.el;
		if(this.emptyText){
			if(el.dom.value==this.emptyText){
				this.setRawValue('');
			}
			el.removeClass(this.emptyClass);
		}
		if(this.selectOnFocus){
			(function(){
				el.dom.select();
			}).defer(this.inEditor&&Ext.isIE?50:0);
		}
	},
	postBlur:function(){
		this.applyEmptyText();
	},
	filterKeys:function(e){
		if(e.ctrlKey||e.isSpecialKey()){
			return;
		}
		if(!this.maskRe.test(String.fromCharCode(e.getCharCode()))){
			e.stopEvent();
		}
	},
	setValue:function(v){
		if(this.emptyText&&this.el&&!Ext.isEmpty(v)){
			this.el.removeClass(this.emptyClass);
		}
		Ext.form.TextField.superclass.setValue.apply(this,arguments);
		this.applyEmptyText();
		this.autoSize();
		return this;
	},
	validateValue:function(value){
		if(Ext.isFunction(this.validator)){
			var msg=this.validator(value);
			if(msg!==true){
				this.markInvalid(msg);
				return false;
			}
		}
		if(value.length<1||value===this.emptyText){
			 if(this.allowBlank){
				 this.clearInvalid();
				 return true;
			}else{
				 this.markInvalid(this.blankText);
				 return false;
			}
		}
		if(value.length<this.minLength){
			this.markInvalid(String.format(this.minLengthText,this.minLength));
			return false;
		}
		if(value.length>this.maxLength){
			this.markInvalid(String.format(this.maxLengthText,this.maxLength));
			return false;
		}
		if(this.vtype){
			var vt=Ext.form.VTypes;
			if(!vt[this.vtype](value,this)){
				this.markInvalid(this.vtypeText||vt[this.vtype+'Text']);
				return false;
			}
		}
		if(this.regex&&!this.regex.test(value)){
			this.markInvalid(this.regexText);
			return false;
		}
		return true;
	},
	selectText:function(start,end){
		var v=this.getRawValue();
		var doFocus=false;
		if(v.length>0){
			start=start===undefined?0:start;
			end=end===undefined?v.length:end;
			var d=this.el.dom;
			if(d.setSelectionRange){
				d.setSelectionRange(start,end);
			}else if(d.createTextRange){
				var range=d.createTextRange();
				range.moveStart('character',start);
				range.moveEnd('character',end-v.length);
				range.select();
			}
			doFocus=Ext.isGecko||Ext.isOpera;
		}else{
			doFocus=true;
		}
		if(doFocus){
			this.focus();
		}
	},
	autoSize:function(){
		if(!this.grow||!this.rendered){
			return;
		}
		if(!this.metrics){
			this.metrics=Ext.util.TextMetrics.createInstance(this.el);
		}
		var el=this.el;
		var v=el.dom.value;
		var d=document.createElement('div');
		d.appendChild(document.createTextNode(v));
		v=d.innerHTML;
		d=null;
		Ext.removeNode(d);
		v+='&#160;';
		var w=Math.min(this.growMax,Math.max(this.metrics.getWidth(v)+10,this.growMin));
		this.el.setWidth(w);
		this.fireEvent('autosize',this,w);
	},
	onDestroy:function(){
		if(this.validationTask){
			this.validationTask.cancel();
			this.validationTask=null;
		}
		Ext.form.TextField.superclass.onDestroy.call(this);
	}});
Ext.reg('textfield',Ext.form.TextField);
Ext.form.TriggerField=Ext.extend(Ext.form.TextField,{
	defaultAutoCreate:{tag:"input",type:"text",size:"16",autocomplete:"off"},
	hideTrigger:false,
	editable:true,
	wrapFocusClass:'x-trigger-wrap-focus',
	autoSize:Ext.emptyFn,
	monitorTab:true,
	deferHeight:true,
	mimicing:false,
	actionMode:'wrap',
	onResize:function(w,h){
		Ext.form.TriggerField.superclass.onResize.call(this,w,h);
		if(typeof w=='number'){
			this.el.setWidth(this.adjustWidth('input',w-this.trigger.getWidth()));
		}
		this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
	},
	adjustSize:Ext.BoxComponent.prototype.adjustSize,
	getResizeEl:function(){
		return this.wrap;
	},
	getPositionEl:function(){
		return this.wrap;
	},
	alignErrorIcon:function(){
		if(this.wrap){
			this.errorIcon.alignTo(this.wrap,'tl-tr',[2,0]);
		}
	},
	onRender:function(ct,position){
		Ext.form.TriggerField.superclass.onRender.call(this,ct,position);
		this.wrap=this.el.wrap({cls:'x-form-field-wrap x-form-field-trigger-wrap'});
		this.trigger=this.wrap.createChild(this.triggerConfig||
				{tag:"img",src:Ext.BLANK_IMAGE_URL,cls:"x-form-trigger "+this.triggerClass});
		if(this.hideTrigger){
			this.trigger.setDisplayed(false);
		}
		this.initTrigger();
		if(!this.width){
			this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
		}
		if(!this.editable){
			this.editable=true;
			this.setEditable(false);
		}
	},
	afterRender:function(){
		Ext.form.TriggerField.superclass.afterRender.call(this);
	},
	initTrigger:function(){
		this.mon(this.trigger,'click',this.onTriggerClick,this,{preventDefault:true});
		this.trigger.addClassOnOver('x-form-trigger-over');
		this.trigger.addClassOnClick('x-form-trigger-click');
	},
	onDestroy:function(){
		Ext.destroy(this.trigger,this.wrap);
		if(this.mimicing){
			Ext.get(Ext.isIE?document.body:document).un("mousedown",this.mimicBlur,this);
		}
		Ext.form.TriggerField.superclass.onDestroy.call(this);
	},
	onFocus:function(){
		Ext.form.TriggerField.superclass.onFocus.call(this);
		if(!this.mimicing){
			this.wrap.addClass(this.wrapFocusClass);
			this.mimicing=true;
			Ext.get(Ext.isIE?document.body:document).on("mousedown",this.mimicBlur,this,{delay:10});
			if(this.monitorTab){
				this.el.on('keydown',this.checkTab,this);
			}
		}
	},
	checkTab:function(e){
		if(e.getKey()==e.TAB){
			this.triggerBlur();
		}
	},
	onBlur:function(){
	},
	mimicBlur:function(e){
		if(!this.wrap.contains(e.target)&&this.validateBlur(e)){
			this.triggerBlur();
		}
	},
	triggerBlur:function(){
		this.mimicing=false;
		Ext.get(Ext.isIE?document.body:document).un("mousedown",this.mimicBlur,this);
		if(this.monitorTab&&this.el){
			this.el.un("keydown",this.checkTab,this);
		}
		Ext.form.TriggerField.superclass.onBlur.call(this);
		if(this.wrap){
			this.wrap.removeClass(this.wrapFocusClass);
		}
	},
	beforeBlur:Ext.emptyFn,
	setEditable:function(value){
		if(value==this.editable){
			return;
		}
		this.editable=value;
		if(!value){
			this.el.addClass('x-trigger-noedit').on('click',this.onTriggerClick,this).dom.setAttribute('readOnly',true);
		}else{
			this.el.removeClass('x-trigger-noedit').un('click',this.onTriggerClick,this).dom.removeAttribute('readOnly');
		}
	},
	validateBlur:function(e){
		return true;
	},
	onTriggerClick:Ext.emptyFn
	});
Ext.form.TwinTriggerField=Ext.extend(Ext.form.TriggerField,{
	initComponent:function(){
		Ext.form.TwinTriggerField.superclass.initComponent.call(this);
		this.triggerConfig={
			tag:'span',cls:'x-form-twin-triggers',cn:[
			{tag:"img",src:Ext.BLANK_IMAGE_URL,cls:"x-form-trigger "+this.trigger1Class},
			{tag:"img",src:Ext.BLANK_IMAGE_URL,cls:"x-form-trigger "+this.trigger2Class}
		]};
	},
	getTrigger:function(index){
		return this.triggers[index];
	},
	initTrigger:function(){
		var ts=this.trigger.select('.x-form-trigger',true);
		this.wrap.setStyle('overflow','hidden');
		var triggerField=this;
		ts.each(function(t,all,index){
			t.hide=function(){
				var w=triggerField.wrap.getWidth();
				this.dom.style.display='none';
				triggerField.el.setWidth(w-triggerField.trigger.getWidth());
			};
			t.show=function(){
				var w=triggerField.wrap.getWidth();
				this.dom.style.display='';
				triggerField.el.setWidth(w-triggerField.trigger.getWidth());
			};
			var triggerIndex='Trigger'+(index+1);
			if(this['hide'+triggerIndex]){
				t.dom.style.display='none';
			}
			this.mon(t,'click',this['on'+triggerIndex+'Click'],this,{preventDefault:true});
			t.addClassOnOver('x-form-trigger-over');
			t.addClassOnClick('x-form-trigger-click');
		},this);
		this.triggers=ts.elements;
	},
	onTrigger1Click:Ext.emptyFn,
	onTrigger2Click:Ext.emptyFn});
Ext.reg('trigger',Ext.form.TriggerField);
Ext.form.TextArea=Ext.extend(Ext.form.TextField,{
	growMin:60,
	growMax:1000,
	growAppend:'&#160;\n&#160;',
	growPad:Ext.isWebKit?-6:0,
	enterIsSpecial:false,
	preventScrollbars:false,
	onRender:function(ct,position){
		if(!this.el){
			this.defaultAutoCreate={
				tag:"textarea",
				style:"width:100px;height:60px;",
				autocomplete:"off"
			};
		}
		Ext.form.TextArea.superclass.onRender.call(this,ct,position);
		if(this.grow){
			this.textSizeEl=Ext.DomHelper.append(document.body,{
				tag:"pre",cls:"x-form-grow-sizer"
			});
			if(this.preventScrollbars){
				this.el.setStyle("overflow","hidden");
			}
			this.el.setHeight(this.growMin);
		}
	},
	onDestroy:function(){
		Ext.destroy(this.textSizeEl);
		Ext.form.TextArea.superclass.onDestroy.call(this);
	},
	fireKey:function(e){
		if(e.isSpecialKey()&&(this.enterIsSpecial||(e.getKey()!=e.ENTER||e.hasModifier()))){
			this.fireEvent("specialkey",this,e);
		}
	},
	onKeyUp:function(e){
		if(!e.isNavKeyPress()||e.getKey()==e.ENTER){
			this.autoSize();
		}
		Ext.form.TextArea.superclass.onKeyUp.call(this,e);
	},
	autoSize:function(){
		if(!this.grow||!this.textSizeEl){
			return;
		}
		var el=this.el;
		var v=el.dom.value;
		var ts=this.textSizeEl;
		ts.innerHTML='';
		ts.appendChild(document.createTextNode(v));
		v=ts.innerHTML;
		Ext.fly(ts).setWidth(this.el.getWidth());
		if(v.length<1){
			v="&#160;&#160;";
		}else{
			v+=this.growAppend;
			if(Ext.isIE){
				v=v.replace(/\n/g,'<br />');
			}
		}
		ts.innerHTML=v;
		var h=Math.min(this.growMax,Math.max(ts.offsetHeight,this.growMin)+this.growPad);
		if(h!=this.lastHeight){
			this.lastHeight=h;
			this.el.setHeight(h);
			this.fireEvent("autosize",this,h);
		}
	}});
Ext.reg('textarea',Ext.form.TextArea);
Ext.form.NumberField=Ext.extend(Ext.form.TextField,{
	fieldClass:"x-form-field x-form-num-field",
	allowDecimals:true,
	decimalSeparator:".",
	decimalPrecision:2,
	allowNegative:true,
	minValue:Number.NEGATIVE_INFINITY,
	maxValue:Number.MAX_VALUE,
	minText:"The minimum value for this field is {0}",
	maxText:"The maximum value for this field is {0}",
	nanText:"{0} is not a valid number",
	baseChars:"0123456789",
	initEvents:function(){
		var allowed=this.baseChars+'';
		if(this.allowDecimals){
			allowed+=this.decimalSeparator;
		}
		if(this.allowNegative){
			allowed+='-';
		}
		this.maskRe=new RegExp('['+Ext.escapeRe(allowed)+']');
		Ext.form.NumberField.superclass.initEvents.call(this);
	},
	validateValue:function(value){
		if(!Ext.form.NumberField.superclass.validateValue.call(this,value)){
			return false;
		}
		if(value.length<1){
			 return true;
		}
		value=String(value).replace(this.decimalSeparator,".");
		if(isNaN(value)){
			this.markInvalid(String.format(this.nanText,value));
			return false;
		}
		var num=this.parseValue(value);
		if(num<this.minValue){
			this.markInvalid(String.format(this.minText,this.minValue));
			return false;
		}
		if(num>this.maxValue){
			this.markInvalid(String.format(this.maxText,this.maxValue));
			return false;
		}
		return true;
	},
	getValue:function(){
		return this.fixPrecision(this.parseValue(Ext.form.NumberField.superclass.getValue.call(this)));
	},
	setValue:function(v){
		v=typeof v=='number'?v:parseFloat(String(v).replace(this.decimalSeparator,"."));
		v=isNaN(v)?'':String(v).replace(".",this.decimalSeparator);
		return Ext.form.NumberField.superclass.setValue.call(this,v);
	},
	parseValue:function(value){
		value=parseFloat(String(value).replace(this.decimalSeparator,"."));
		return isNaN(value)?'':value;
	},
	fixPrecision:function(value){
		var nan=isNaN(value);
		if(!this.allowDecimals||this.decimalPrecision==-1||nan||!value){
		 return nan?'':value;
		}
		return parseFloat(parseFloat(value).toFixed(this.decimalPrecision));
	},
	beforeBlur:function(){
		var v=this.parseValue(this.getRawValue());
		if(!Ext.isEmpty(v)){
			this.setValue(this.fixPrecision(v));
		}
	}});
Ext.reg('numberfield',Ext.form.NumberField);
Ext.form.DateField=Ext.extend(Ext.form.TriggerField,{
	format:"m/d/Y",
	altFormats:"m/d/Y|n/j/Y|n/j/y|m/j/y|n/d/y|m/j/Y|n/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d|Y-m-d",
	disabledDaysText:"Disabled",
	disabledDatesText:"Disabled",
	minText:"The date in this field must be equal to or after {0}",
	maxText:"The date in this field must be equal to or before {0}",
	invalidText:"{0} is not a valid date - it must be in the format {1}",
	triggerClass:'x-form-date-trigger',
	showToday:true,
	defaultAutoCreate:{tag:"input",type:"text",size:"10",autocomplete:"off"},
	initComponent:function(){
		Ext.form.DateField.superclass.initComponent.call(this);
		this.addEvents(
			'select'
		);
		if(Ext.isString(this.minValue)){
			this.minValue=this.parseDate(this.minValue);
		}
		if(Ext.isString(this.maxValue)){
			this.maxValue=this.parseDate(this.maxValue);
		}
		this.disabledDatesRE=null;
		this.initDisabledDays();
	},
	initDisabledDays:function(){
		if(this.disabledDates){
			var dd=this.disabledDates,
				len=dd.length-1,
				re="(?:";
			Ext.each(dd,function(d,i){
				re+=Ext.isDate(d)?'^'+Ext.escapeRe(d.dateFormat(this.format))+'$':dd[i];
				if(i!=len){
					re+='|';
				}
			},this);
			this.disabledDatesRE=new RegExp(re+')');
		}
	},
	setDisabledDates:function(dd){
		this.disabledDates=dd;
		this.initDisabledDays();
		if(this.menu){
			this.menu.picker.setDisabledDates(this.disabledDatesRE);
		}
	},
	setDisabledDays:function(dd){
		this.disabledDays=dd;
		if(this.menu){
			this.menu.picker.setDisabledDays(dd);
		}
	},
	setMinValue:function(dt){
		this.minValue=(Ext.isString(dt)?this.parseDate(dt):dt);
		if(this.menu){
			this.menu.picker.setMinDate(this.minValue);
		}
	},
	setMaxValue:function(dt){
		this.maxValue=(Ext.isString(dt)?this.parseDate(dt):dt);
		if(this.menu){
			this.menu.picker.setMaxDate(this.maxValue);
		}
	},
	validateValue:function(value){
		value=this.formatDate(value);
		if(!Ext.form.DateField.superclass.validateValue.call(this,value)){
			return false;
		}
		if(value.length<1){
			 return true;
		}
		var svalue=value;
		value=this.parseDate(value);
		if(!value){
			this.markInvalid(String.format(this.invalidText,svalue,this.format));
			return false;
		}
		var time=value.getTime();
		if(this.minValue&&time<this.minValue.getTime()){
			this.markInvalid(String.format(this.minText,this.formatDate(this.minValue)));
			return false;
		}
		if(this.maxValue&&time>this.maxValue.getTime()){
			this.markInvalid(String.format(this.maxText,this.formatDate(this.maxValue)));
			return false;
		}
		if(this.disabledDays){
			var day=value.getDay();
			for(var i=0;i<this.disabledDays.length;i++){
				if(day===this.disabledDays[i]){
					this.markInvalid(this.disabledDaysText);
					return false;
				}
			}
		}
		var fvalue=this.formatDate(value);
		if(this.disabledDatesRE&&this.disabledDatesRE.test(fvalue)){
			this.markInvalid(String.format(this.disabledDatesText,fvalue));
			return false;
		}
		return true;
	},
	validateBlur:function(){
		return!this.menu||!this.menu.isVisible();
	},
	getValue:function(){
		return this.parseDate(Ext.form.DateField.superclass.getValue.call(this))||"";
	},
	setValue:function(date){
		return Ext.form.DateField.superclass.setValue.call(this,this.formatDate(this.parseDate(date)));
	},
	parseDate:function(value){
		if(!value||Ext.isDate(value)){
			return value;
		}
		var v=Date.parseDate(value,this.format);
		if(!v&&this.altFormats){
			if(!this.altFormatsArray){
				this.altFormatsArray=this.altFormats.split("|");
			}
			for(var i=0,len=this.altFormatsArray.length;i<len&&!v;i++){
				v=Date.parseDate(value,this.altFormatsArray[i]);
			}
		}
		return v;
	},
	onDestroy:function(){
		Ext.destroy(this.menu);
		Ext.form.DateField.superclass.onDestroy.call(this);
	},
	formatDate:function(date){
		return Ext.isDate(date)?date.dateFormat(this.format):date;
	},
	onTriggerClick:function(){
		if(this.disabled){
			return;
		}
		if(this.menu==null){
			this.menu=new Ext.menu.DateMenu({
				hideOnClick:false
			});
		}
		this.onFocus();
		Ext.apply(this.menu.picker,{
			minDate:this.minValue,
			maxDate:this.maxValue,
			disabledDatesRE:this.disabledDatesRE,
			disabledDatesText:this.disabledDatesText,
			disabledDays:this.disabledDays,
			disabledDaysText:this.disabledDaysText,
			format:this.format,
			showToday:this.showToday,
			minText:String.format(this.minText,this.formatDate(this.minValue)),
			maxText:String.format(this.maxText,this.formatDate(this.maxValue))
		});
		this.menu.picker.setValue(this.getValue()||new Date());
		this.menu.show(this.el,"tl-bl?");
		this.menuEvents('on');
	},
	menuEvents:function(method){
		this.menu[method]('select',this.onSelect,this);
		this.menu[method]('hide',this.onMenuHide,this);
		this.menu[method]('show',this.onFocus,this);
	},
	onSelect:function(m,d){
		this.setValue(d);
		this.fireEvent('select',this,d);
		this.menu.hide();
	},
	onMenuHide:function(){
		this.focus(false,60);
		this.menuEvents('un');
	},
	beforeBlur:function(){
		var v=this.parseDate(this.getRawValue());
		if(v){
			this.setValue(v);
		}
	}
	});
Ext.reg('datefield',Ext.form.DateField);
Ext.form.DisplayField=Ext.extend(Ext.form.Field,{
	validationEvent:false,
	validateOnBlur:false,
	defaultAutoCreate:{tag:"div"},
	fieldClass:"x-form-display-field",
	htmlEncode:false,
	initEvents:Ext.emptyFn,
	isValid:function(){
		return true;
	},
	validate:function(){
		return true;
	},
	getRawValue:function(){
		var v=this.rendered?this.el.dom.innerHTML:Ext.value(this.value,'');
		if(v===this.emptyText){
			v='';
		}
		if(this.htmlEncode){
			v=Ext.util.Format.htmlDecode(v);
		}
		return v;
	},
	getValue:function(){
		return this.getRawValue();
	},
	getName:function(){
		return this.name;
	},
	setRawValue:function(v){
		if(this.htmlEncode){
			v=Ext.util.Format.htmlEncode(v);
		}
		return this.rendered?(this.el.dom.innerHTML=(Ext.isEmpty(v)?'':v)):(this.value=v);
	},
	setValue:function(v){
		this.setRawValue(v);
		return this;
	}
	});
Ext.reg('displayfield',Ext.form.DisplayField);
Ext.form.ComboBox=Ext.extend(Ext.form.TriggerField,{
	defaultAutoCreate:{tag:"input",type:"text",size:"24",autocomplete:"off"},
	listClass:'',
	selectedClass:'x-combo-selected',
	listEmptyText:'',
	triggerClass:'x-form-arrow-trigger',
	shadow:'sides',
	listAlign:'tl-bl?',
	maxHeight:300,
	minHeight:90,
	triggerAction:'query',
	minChars:4,
	typeAhead:false,
	queryDelay:500,
	pageSize:0,
	selectOnFocus:false,
	queryParam:'query',
	loadingText:'Loading...',
	resizable:false,
	handleHeight:8,
	allQuery:'',
	mode:'remote',
	minListWidth:70,
	forceSelection:false,
	typeAheadDelay:250,
	lazyInit:true,
	initComponent:function(){
		Ext.form.ComboBox.superclass.initComponent.call(this);
		this.addEvents(
			'expand',
			'collapse',
			'beforeselect',
			'select',
			'beforequery'
		);
		if(this.transform){
			var s=Ext.getDom(this.transform);
			if(!this.hiddenName){
				this.hiddenName=s.name;
			}
			if(!this.store){
				this.mode='local';
				var d=[],opts=s.options;
				for(var i=0,len=opts.length;i<len;i++){
					var o=opts[i],
						value=(o.hasAttribute?o.hasAttribute('value'):o.getAttributeNode('value').specified)?o.value:o.text;
					if(o.selected&&Ext.isEmpty(this.value,true)){
						this.value=value;
					}
					d.push([value,o.text]);
				}
				this.store=new Ext.data.ArrayStore({
					'id':0,
					fields:['value','text'],
					data:d,
					autoDestroy:true
				});
				this.valueField='value';
				this.displayField='text';
			}
			s.name=Ext.id();
			if(!this.lazyRender){
				this.target=true;
				this.el=Ext.DomHelper.insertBefore(s,this.autoCreate||this.defaultAutoCreate);
				this.render(this.el.parentNode,s);
				Ext.removeNode(s);
			}else{
				Ext.removeNode(s);
			}
		}
		else if(this.store){
			this.store=Ext.StoreMgr.lookup(this.store);
			if(this.store.autoCreated){
				this.displayField=this.valueField='field1';
				if(!this.store.expandData){
					this.displayField='field2';
				}
				this.mode='local';
			}
		}
		this.selectedIndex=-1;
		if(this.mode=='local'){
			if(!Ext.isDefined(this.initialConfig.queryDelay)){
				this.queryDelay=10;
			}
			if(!Ext.isDefined(this.initialConfig.minChars)){
				this.minChars=0;
			}
		}
	},
	onRender:function(ct,position){
		Ext.form.ComboBox.superclass.onRender.call(this,ct,position);
		if(this.hiddenName){
			this.hiddenField=this.el.insertSibling({tag:'input',type:'hidden',name:this.hiddenName,
					id:(this.hiddenId||this.hiddenName)},'before',true);
			this.el.dom.removeAttribute('name');
		}
		if(Ext.isGecko){
			this.el.dom.setAttribute('autocomplete','off');
		}
		if(!this.lazyInit){
			this.initList();
		}else{
			this.on('focus',this.initList,this,{single:true});
		}
	},
	initValue:function(){
		Ext.form.ComboBox.superclass.initValue.call(this);
		if(this.hiddenField){
			this.hiddenField.value=
				Ext.isDefined(this.hiddenValue)?this.hiddenValue:
				Ext.isDefined(this.value)?this.value:'';
		}
	},
	initList:function(){
		if(!this.list){
			var cls='x-combo-list';
			this.list=new Ext.Layer({
				parentEl:this.getListParent(),
				shadow:this.shadow,
				cls:[cls,this.listClass].join(' '),
				constrain:false
			});
			var lw=this.listWidth||Math.max(this.wrap.getWidth(),this.minListWidth);
			this.list.setSize(lw,0);
			this.list.swallowEvent('mousewheel');
			this.assetHeight=0;
			if(this.syncFont!==false){
				this.list.setStyle('font-size',this.el.getStyle('font-size'));
			}
			if(this.title){
				this.header=this.list.createChild({cls:cls+'-hd',html:this.title});
				this.assetHeight+=this.header.getHeight();
			}
			this.innerList=this.list.createChild({cls:cls+'-inner'});
			this.mon(this.innerList,'mouseover',this.onViewOver,this);
			this.mon(this.innerList,'mousemove',this.onViewMove,this);
			this.innerList.setWidth(lw-this.list.getFrameWidth('lr'));
			if(this.pageSize){
				this.footer=this.list.createChild({cls:cls+'-ft'});
				this.pageTb=new Ext.PagingToolbar({
					store:this.store,
					pageSize:this.pageSize,
					renderTo:this.footer
				});
				this.assetHeight+=this.footer.getHeight();
			}
			if(!this.tpl){
				this.tpl='<tpl for="."><div class="'+cls+'-item">{'+this.displayField+'}</div></tpl>';
			}
			this.view=new Ext.DataView({
				applyTo:this.innerList,
				tpl:this.tpl,
				singleSelect:true,
				selectedClass:this.selectedClass,
				itemSelector:this.itemSelector||'.'+cls+'-item',
				emptyText:this.listEmptyText
			});
			this.mon(this.view,'click',this.onViewClick,this);
			this.bindStore(this.store,true);
			if(this.resizable){
				this.resizer=new Ext.Resizable(this.list,{
				 pinned:true,handles:'se'
				});
				this.mon(this.resizer,'resize',function(r,w,h){
					this.maxHeight=h-this.handleHeight-this.list.getFrameWidth('tb')-this.assetHeight;
					this.listWidth=w;
					this.innerList.setWidth(w-this.list.getFrameWidth('lr'));
					this.restrictHeight();
				},this);
				this[this.pageSize?'footer':'innerList'].setStyle('margin-bottom',this.handleHeight+'px');
			}
		}
	},
	getListParent:function(){
		return document.body;
	},
	getStore:function(){
		return this.store;
	},
	bindStore:function(store,initial){
		if(this.store&&!initial){
			this.store.un('beforeload',this.onBeforeLoad,this);
			this.store.un('load',this.onLoad,this);
			this.store.un('exception',this.collapse,this);
			if(this.store!==store&&this.store.autoDestroy){
				this.store.destroy();
			}
			if(!store){
				this.store=null;
				if(this.view){
					this.view.bindStore(null);
				}
			}
		}
		if(store){
			if(!initial){
				this.lastQuery=null;
				if(this.pageTb){
					this.pageTb.bindStore(store);
				}
			}
			this.store=Ext.StoreMgr.lookup(store);
			this.store.on({
				scope:this,
				beforeload:this.onBeforeLoad,
				load:this.onLoad,
				exception:this.collapse
			});
			if(this.view){
				this.view.bindStore(store);
			}
		}
	},
	initEvents:function(){
		Ext.form.ComboBox.superclass.initEvents.call(this);
		this.keyNav=new Ext.KeyNav(this.el,{
			"up":function(e){
				this.inKeyMode=true;
				this.selectPrev();
			},
			"down":function(e){
				if(!this.isExpanded()){
					this.onTriggerClick();
				}else{
					this.inKeyMode=true;
					this.selectNext();
				}
			},
			"enter":function(e){
				this.onViewClick();
				this.delayedCheck=true;
				this.unsetDelayCheck.defer(10,this);
			},
			"esc":function(e){
				this.collapse();
			},
			"tab":function(e){
				this.onViewClick(false);
				return true;
			},
			scope:this,
			doRelay:function(foo,bar,hname){
				if(hname=='down'||this.scope.isExpanded()){
				 return Ext.KeyNav.prototype.doRelay.apply(this,arguments);
				}
				return true;
			},
			forceKeyDown:true
		});
		this.queryDelay=Math.max(this.queryDelay||10,
				this.mode=='local'?10:250);
		this.dqTask=new Ext.util.DelayedTask(this.initQuery,this);
		if(this.typeAhead){
			this.taTask=new Ext.util.DelayedTask(this.onTypeAhead,this);
		}
		if(this.editable!==false&&!this.enableKeyEvents){
			this.mon(this.el,'keyup',this.onKeyUp,this);
		}
	},
	onDestroy:function(){
		if(this.dqTask){
			this.dqTask.cancel();
			this.dqTask=null;
		}
		this.bindStore(null);
		Ext.destroy(
			this.resizer,
			this.view,
			this.pageTb,
			this.list
		);
		Ext.form.ComboBox.superclass.onDestroy.call(this);
	},
	unsetDelayCheck:function(){
		delete this.delayedCheck;
	},
	fireKey:function(e){
		var fn=function(ev){
			if(ev.isNavKeyPress()&&!this.isExpanded()&&!this.delayedCheck){
				this.fireEvent("specialkey",this,ev);
			}
		};
		if(this.inEditor&&Ext.isWebKit&&e.getKey()==e.TAB){
			fn.defer(10,this,[new Ext.EventObjectImpl(e)]);
		}else{
			fn.call(this,e);
		}
	},
	onResize:function(w,h){
		Ext.form.ComboBox.superclass.onResize.apply(this,arguments);
		if(this.list&&!Ext.isDefined(this.listWidth)){
			var lw=Math.max(w,this.minListWidth);
			this.list.setWidth(lw);
			this.innerList.setWidth(lw-this.list.getFrameWidth('lr'));
		}
	},
	onEnable:function(){
		Ext.form.ComboBox.superclass.onEnable.apply(this,arguments);
		if(this.hiddenField){
			this.hiddenField.disabled=false;
		}
	},
	onDisable:function(){
		Ext.form.ComboBox.superclass.onDisable.apply(this,arguments);
		if(this.hiddenField){
			this.hiddenField.disabled=true;
		}
	},
	onBeforeLoad:function(){
		if(!this.hasFocus){
			return;
		}
		this.innerList.update(this.loadingText?
			'<div class="loading-indicator">'+this.loadingText+'</div>':'');
		this.restrictHeight();
		this.selectedIndex=-1;
	},
	onLoad:function(){
		if(!this.hasFocus){
			return;
		}
		if(this.store.getCount()>0){
			this.expand();
			this.restrictHeight();
			if(this.lastQuery==this.allQuery){
				if(this.editable){
					this.el.dom.select();
				}
				if(!this.selectByValue(this.value,true)){
					this.select(0,true);
				}
			}else{
				this.selectNext();
				if(this.typeAhead&&this.lastKey!=Ext.EventObject.BACKSPACE&&this.lastKey!=Ext.EventObject.DELETE){
					this.taTask.delay(this.typeAheadDelay);
				}
			}
		}else{
			this.onEmptyResults();
		}
	},
	onTypeAhead:function(){
		if(this.store.getCount()>0){
			var r=this.store.getAt(0);
			var newValue=r.data[this.displayField];
			var len=newValue.length;
			var selStart=this.getRawValue().length;
			if(selStart!=len){
				this.setRawValue(newValue);
				this.selectText(selStart,newValue.length);
			}
		}
	},
	onSelect:function(record,index){
		if(this.fireEvent('beforeselect',this,record,index)!==false){
			this.setValue(record.data[this.valueField||this.displayField]);
			this.collapse();
			this.fireEvent('select',this,record,index);
		}
	},
	getName:function(){
		var hf=this.hiddenField;
		return hf&&hf.name?hf.name:this.hiddenName||Ext.form.ComboBox.superclass.getName.call(this);
	},
	getValue:function(){
		if(this.valueField){
			return Ext.isDefined(this.value)?this.value:'';
		}else{
			return Ext.form.ComboBox.superclass.getValue.call(this);
		}
	},
	clearValue:function(){
		if(this.hiddenField){
			this.hiddenField.value='';
		}
		this.setRawValue('');
		this.lastSelectionText='';
		this.applyEmptyText();
		this.value='';
	},
	setValue:function(v){
		var text=v;
		if(this.valueField){
			var r=this.findRecord(this.valueField,v);
			if(r){
				text=r.data[this.displayField];
			}else if(Ext.isDefined(this.valueNotFoundText)){
				text=this.valueNotFoundText;
			}
		}
		this.lastSelectionText=text;
		if(this.hiddenField){
			this.hiddenField.value=v;
		}
		Ext.form.ComboBox.superclass.setValue.call(this,text);
		this.value=v;
		return this;
	},
	findRecord:function(prop,value){
		var record;
		if(this.store.getCount()>0){
			this.store.each(function(r){
				if(r.data[prop]==value){
					record=r;
					return false;
				}
			});
		}
		return record;
	},
	onViewMove:function(e,t){
		this.inKeyMode=false;
	},
	onViewOver:function(e,t){
		if(this.inKeyMode){
			return;
		}
		var item=this.view.findItemFromChild(t);
		if(item){
			var index=this.view.indexOf(item);
			this.select(index,false);
		}
	},
	onViewClick:function(doFocus){
		var index=this.view.getSelectedIndexes()[0];
		var r=this.store.getAt(index);
		if(r){
			this.onSelect(r,index);
		}
		if(doFocus!==false){
			this.el.focus();
		}
	},
	restrictHeight:function(){
		this.innerList.dom.style.height='';
		var inner=this.innerList.dom;
		var pad=this.list.getFrameWidth('tb')+(this.resizable?this.handleHeight:0)+this.assetHeight;
		var h=Math.max(inner.clientHeight,inner.offsetHeight,inner.scrollHeight);
		var ha=this.getPosition()[1]-Ext.getBody().getScroll().top;
		var hb=Ext.lib.Dom.getViewHeight()-ha-this.getSize().height;
		var space=Math.max(ha,hb,this.minHeight||0)-this.list.shadowOffset-pad-5;
		h=Math.min(h,space,this.maxHeight);
		this.innerList.setHeight(h);
		this.list.beginUpdate();
		this.list.setHeight(h+pad);
		this.list.alignTo(this.wrap,this.listAlign);
		this.list.endUpdate();
	},
	onEmptyResults:function(){
		this.collapse();
	},
	isExpanded:function(){
		return this.list&&this.list.isVisible();
	},
	selectByValue:function(v,scrollIntoView){
		if(!Ext.isEmpty(v,true)){
			var r=this.findRecord(this.valueField||this.displayField,v);
			if(r){
				this.select(this.store.indexOf(r),scrollIntoView);
				return true;
			}
		}
		return false;
	},
	select:function(index,scrollIntoView){
		this.selectedIndex=index;
		this.view.select(index);
		if(scrollIntoView!==false){
			var el=this.view.getNode(index);
			if(el){
				this.innerList.scrollChildIntoView(el,false);
			}
		}
	},
	selectNext:function(){
		var ct=this.store.getCount();
		if(ct>0){
			if(this.selectedIndex==-1){
				this.select(0);
			}else if(this.selectedIndex<ct-1){
				this.select(this.selectedIndex+1);
			}
		}
	},
	selectPrev:function(){
		var ct=this.store.getCount();
		if(ct>0){
			if(this.selectedIndex==-1){
				this.select(0);
			}else if(this.selectedIndex!==0){
				this.select(this.selectedIndex-1);
			}
		}
	},
	onKeyUp:function(e){
		var k=e.getKey();
		if(this.editable!==false&&(k==e.BACKSPACE||!e.isSpecialKey())){
			this.lastKey=k;
			this.dqTask.delay(this.queryDelay);
		}
		Ext.form.ComboBox.superclass.onKeyUp.call(this,e);
	},
	validateBlur:function(){
		return!this.list||!this.list.isVisible();
	},
	initQuery:function(){
		this.doQuery(this.getRawValue());
	},
	beforeBlur:function(){
		var val=this.getRawValue();
		if(this.forceSelection){
			if(val.length>0&&val!=this.emptyText){
			 this.el.dom.value=Ext.isDefined(this.lastSelectionText)?this.lastSelectionText:'';
				this.applyEmptyText();
			}else{
				this.clearValue();
			}
		}else{
			var rec=this.findRecord(this.displayField,val);
			if(rec){
				val=rec.get(this.valueField||this.displayField);
			}
			this.setValue(val);
		}
	},
	doQuery:function(q,forceAll){
		q=Ext.isEmpty(q)?'':q;
		var qe={
			query:q,
			forceAll:forceAll,
			combo:this,
			cancel:false
		};
		if(this.fireEvent('beforequery',qe)===false||qe.cancel){
			return false;
		}
		q=qe.query;
		forceAll=qe.forceAll;
		if(forceAll===true||(q.length>=this.minChars)){
			if(this.lastQuery!==q){
				this.lastQuery=q;
				if(this.mode=='local'){
					this.selectedIndex=-1;
					if(forceAll){
						this.store.clearFilter();
					}else{
						this.store.filter(this.displayField,q);
					}
					this.onLoad();
				}else{
					this.store.baseParams[this.queryParam]=q;
					this.store.load({
						params:this.getParams(q)
					});
					this.expand();
				}
			}else{
				this.selectedIndex=-1;
				this.onLoad();
			}
		}
	},
	getParams:function(q){
		var p={};
		if(this.pageSize){
			p.start=0;
			p.limit=this.pageSize;
		}
		return p;
	},
	collapse:function(){
		if(!this.isExpanded()){
			return;
		}
		this.list.hide();
		Ext.getDoc().un('mousewheel',this.collapseIf,this);
		Ext.getDoc().un('mousedown',this.collapseIf,this);
		this.fireEvent('collapse',this);
	},
	collapseIf:function(e){
		if(!e.within(this.wrap)&&!e.within(this.list)){
			this.collapse();
		}
	},
	expand:function(){
		if(this.isExpanded()||!this.hasFocus){
			return;
		}
		this.list.alignTo(this.wrap,this.listAlign);
		this.list.show();
		if(Ext.isGecko2){
			this.innerList.setOverflow('auto');
		}
		Ext.getDoc().on({
			scope:this,
			mousewheel:this.collapseIf,
			mousedown:this.collapseIf
		});
		this.fireEvent('expand',this);
	},
	onTriggerClick:function(){
		if(this.disabled){
			return;
		}
		if(this.isExpanded()){
			this.collapse();
			this.el.focus();
		}else{
			this.onFocus({});
			if(this.triggerAction=='all'){
				this.doQuery(this.allQuery,true);
			}else{
				this.doQuery(this.getRawValue());
			}
			this.el.focus();
		}
	}
	});
Ext.reg('combo',Ext.form.ComboBox);
Ext.form.Checkbox=Ext.extend(Ext.form.Field,{
	focusClass:undefined,
	fieldClass:'x-form-field',
	checked:false,
	defaultAutoCreate:{tag:'input',type:'checkbox',autocomplete:'off'},
	actionMode:'wrap',
	initComponent:function(){
		Ext.form.Checkbox.superclass.initComponent.call(this);
		this.addEvents(
			'check'
		);
	},
	onResize:function(){
		Ext.form.Checkbox.superclass.onResize.apply(this,arguments);
		if(!this.boxLabel&&!this.fieldLabel){
			this.el.alignTo(this.wrap,'c-c');
		}
	},
	initEvents:function(){
		Ext.form.Checkbox.superclass.initEvents.call(this);
		this.mon(this.el,'click',this.onClick,this);
		this.mon(this.el,'change',this.onClick,this);
	},
	getResizeEl:function(){
		return this.wrap;
	},
	getPositionEl:function(){
		return this.wrap;
	},
	markInvalid:Ext.emptyFn,
	clearInvalid:Ext.emptyFn,
	onRender:function(ct,position){
		Ext.form.Checkbox.superclass.onRender.call(this,ct,position);
		if(this.inputValue!==undefined){
			this.el.dom.value=this.inputValue;
		}
		this.wrap=this.el.wrap({cls:'x-form-check-wrap'});
		if(this.boxLabel){
			this.wrap.createChild({tag:'label',htmlFor:this.el.id,cls:'x-form-cb-label',html:this.boxLabel});
		}
		if(this.checked){
			this.setValue(true);
		}else{
			this.checked=this.el.dom.checked;
		}
	},
	onDestroy:function(){
		Ext.destroy(this.wrap);
		Ext.form.Checkbox.superclass.onDestroy.call(this);
	},
	initValue:function(){
		this.originalValue=this.getValue();
	},
	getValue:function(){
		if(this.rendered){
			return this.el.dom.checked;
		}
		return false;
	},
	onClick:function(){
		if(this.el.dom.checked!=this.checked){
			this.setValue(this.el.dom.checked);
		}
	},
	setValue:function(v){
		var checked=this.checked;
		this.checked=(v===true||v==='true'||v=='1'||String(v).toLowerCase()=='on');
		if(this.rendered){
			this.el.dom.checked=this.checked;
			this.el.dom.defaultChecked=this.checked;
		}
		if(checked!=this.checked){
			this.fireEvent('check',this,this.checked);
			if(this.handler){
				this.handler.call(this.scope||this,this,this.checked);
			}
		}
		return this;
	}});
Ext.reg('checkbox',Ext.form.Checkbox);
Ext.form.CheckboxGroup=Ext.extend(Ext.form.Field,{
	columns:'auto',
	vertical:false,
	allowBlank:true,
	blankText:"You must select at least one item in this group",
	defaultType:'checkbox',
	groupCls:'x-form-check-group',
	initComponent:function(){
		this.addEvents(
			'change'
		);
		Ext.form.CheckboxGroup.superclass.initComponent.call(this);
	},
	onRender:function(ct,position){
		if(!this.el){
			var panelCfg={
				cls:this.groupCls,
				layout:'column',
				border:false,
				renderTo:ct
			};
			var colCfg={
				defaultType:this.defaultType,
				layout:'form',
				border:false,
				defaults:{
					hideLabel:true,
					anchor:'100%'
				}
			};
			if(this.items[0].items){
				Ext.apply(panelCfg,{
					layoutConfig:{columns:this.items.length},
					defaults:this.defaults,
					items:this.items
				});
				for(var i=0,len=this.items.length;i<len;i++){
					Ext.applyIf(this.items[i],colCfg);
				}
			}else{
				var numCols,cols=[];
				if(typeof this.columns=='string'){
					this.columns=this.items.length;
				}
				if(!Ext.isArray(this.columns)){
					var cs=[];
					for(var i=0;i<this.columns;i++){
						cs.push((100/this.columns)*.01);
					}
					this.columns=cs;
				}
				numCols=this.columns.length;
				for(var i=0;i<numCols;i++){
					var cc=Ext.apply({items:[]},colCfg);
					cc[this.columns[i]<=1?'columnWidth':'width']=this.columns[i];
					if(this.defaults){
						cc.defaults=Ext.apply(cc.defaults||{},this.defaults)
					}
					cols.push(cc);
				};
				if(this.vertical){
					var rows=Math.ceil(this.items.length/numCols),ri=0;
					for(var i=0,len=this.items.length;i<len;i++){
						if(i>0&&i%rows==0){
							ri++;
						}
						if(this.items[i].fieldLabel){
							this.items[i].hideLabel=false;
						}
						cols[ri].items.push(this.items[i]);
					};
				}else{
					for(var i=0,len=this.items.length;i<len;i++){
						var ci=i%numCols;
						if(this.items[i].fieldLabel){
							this.items[i].hideLabel=false;
						}
						cols[ci].items.push(this.items[i]);
					};
				}
				Ext.apply(panelCfg,{
					layoutConfig:{columns:numCols},
					items:cols
				});
			}
			this.panel=new Ext.Panel(panelCfg);
			this.panel.ownerCt=this;
			this.el=this.panel.getEl();
			if(this.forId&&this.itemCls){
				var l=this.el.up(this.itemCls).child('label',true);
				if(l){
					l.setAttribute('htmlFor',this.forId);
				}
			}
			var fields=this.panel.findBy(function(c){
				return c.isFormField;
			},this);
			this.items=new Ext.util.MixedCollection();
			this.items.addAll(fields);
		}
		Ext.form.CheckboxGroup.superclass.onRender.call(this,ct,position);
	},
	afterRender:function(){
		Ext.form.CheckboxGroup.superclass.afterRender.call(this);
		if(this.values){
			this.setValue.apply(this,this.values);
			delete this.values;
		}
		this.eachItem(function(item){
			item.on('check',this.fireChecked,this);
			item.inGroup=true;
		});
	},
	doLayout:function(){
		if(this.rendered){
			this.panel.forceLayout=this.ownerCt.forceLayout;
			this.panel.doLayout();
		}
	},
	fireChecked:function(){
		var arr=[];
		this.eachItem(function(item){
			if(item.checked){
				arr.push(item);
			}
		});
		this.fireEvent('change',this,arr);
	},
	validateValue:function(value){
		if(!this.allowBlank){
			var blank=true;
			this.eachItem(function(f){
				if(f.checked){
					return(blank=false);
				}
			});
			if(blank){
				this.markInvalid(this.blankText);
				return false;
			}
		}
		return true;
	},
	onDisable:function(){
		this.eachItem(function(item){
			item.disable();
		});
	},
	onEnable:function(){
		this.eachItem(function(item){
			item.enable();
		});
	},
	doLayout:function(){
		if(this.rendered){
			this.panel.forceLayout=this.ownerCt.forceLayout;
			this.panel.doLayout();
		}
	},
	onResize:function(w,h){
		this.panel.setSize(w,h);
		this.panel.doLayout();
	},
	reset:function(){
		Ext.form.CheckboxGroup.superclass.reset.call(this);
		this.eachItem(function(c){
			if(c.reset){
				c.reset();
			}
		});
	},
	setValue:function(id,value){
		if(this.rendered){
			if(arguments.length==1){
				if(Ext.isArray(id)){
					Ext.each(id,function(val,idx){
						var item=this.items.itemAt(idx);
						if(item){
							item.setValue(val);
						}
					},this);
				}else if(Ext.isObject(id)){
					for(var i in id){
						var f=this.getBox(i);
						if(f){
							f.setValue(id[i]);
						}
					}
				}else{
					this.setValueForItem(id);
				}
			}else{
				var f=this.getBox(id);
				if(f){
					f.setValue(value);
				}
			}
		}else{
			this.values=arguments;
		}
		return this;
	},
	onDestroy:function(){
		Ext.destroy(this.panel);
		Ext.form.CheckboxGroup.superclass.onDestroy.call(this);
	},
	setValueForItem:function(val){
		val=String(val).split(',');
		this.eachItem(function(item){
			if(val.indexOf(item.inputValue)>-1){
				item.setValue(true);
			}
		});
	},
	getBox:function(id){
		var box=null;
		this.eachItem(function(f){
			if(id==f||f.dataIndex==id||f.id==id||f.getName()==id){
				box=f;
				return false;
			}
		});
		return box;
	},
	getValue:function(){
		var out=[];
		this.eachItem(function(item){
			if(item.checked){
				out.push(item);
			}
		});
		return out;
	},
	eachItem:function(fn){
		if(this.items&&this.items.each){
			this.items.each(fn,this);
		}
	},
	initValue:Ext.emptyFn,
	getValue:Ext.emptyFn,
	getRawValue:Ext.emptyFn,
	setRawValue:Ext.emptyFn});
Ext.reg('checkboxgroup',Ext.form.CheckboxGroup);
Ext.form.Radio=Ext.extend(Ext.form.Checkbox,{
	inputType:'radio',
	markInvalid:Ext.emptyFn,
	clearInvalid:Ext.emptyFn,
	getGroupValue:function(){
		var p=this.el.up('form')||Ext.getBody();
		var c=p.child('input[name='+this.el.dom.name+']:checked',true);
		return c?c.value:null;
	},
	onClick:function(){
		if(this.el.dom.checked!=this.checked){
			var els=this.getCheckEl().select('input[name='+this.el.dom.name+']');
			els.each(function(el){
				if(el.dom.id==this.id){
					this.setValue(true);
				}else{
					Ext.getCmp(el.dom.id).setValue(false);
				}
			},this);
		}
	},
	setValue:function(v){
		if(typeof v=='boolean'){
			Ext.form.Radio.superclass.setValue.call(this,v);
		}else{
			var r=this.getCheckEl().child('input[name='+this.el.dom.name+'][value='+v+']',true);
			if(r){
				Ext.getCmp(r.id).setValue(true);
			}
		}
		return this;
	},
	getCheckEl:function(){
		if(this.inGroup){
			return this.el.up('.x-form-radio-group')
		}
		return this.el.up('form')||Ext.getBody();
	}});
Ext.reg('radio',Ext.form.Radio);
Ext.form.RadioGroup=Ext.extend(Ext.form.CheckboxGroup,{
	allowBlank:true,
	blankText:'You must select one item in this group',
	defaultType:'radio',
	groupCls:'x-form-radio-group',
	getValue:function(){
		var out=null;
		this.eachItem(function(item){
			if(item.checked){
				out=item;
				return false;
			}
		});
		return out;
	},
	setValue:function(id,value){
		if(this.rendered){
			if(arguments.length>1){
				var f=this.getBox(id);
				if(f){
					f.setValue(value);
					if(f.checked){
						this.eachItem(function(item){
							if(item!==f){
								item.setValue(false);
							}
						});
					}
				}
			}else{
				this.setValueForItem(id);
			}
		}else{
			this.values=arguments;
		}
		return this;
	},
	fireChecked:function(){
		if(!this.checkTask){
			this.checkTask=new Ext.util.DelayedTask(this.bufferChecked,this);
		}
		this.checkTask.delay(10);
	},
	bufferChecked:function(){
		var out=null;
		this.eachItem(function(item){
			if(item.checked){
				out=item;
				return false;
			}
		});
		this.fireEvent('change',this,out);
	},
	onDestroy:function(){
		if(this.checkTask){
			this.checkTask.cancel();
			this.checkTask=null;
		}
		Ext.form.RadioGroup.superclass.onDestroy.call(this);
	}});
Ext.reg('radiogroup',Ext.form.RadioGroup);
Ext.form.Hidden=Ext.extend(Ext.form.Field,{
	inputType:'hidden',
	onRender:function(){
		Ext.form.Hidden.superclass.onRender.apply(this,arguments);
	},
	initEvents:function(){
		this.originalValue=this.getValue();
	},
	setSize:Ext.emptyFn,
	setWidth:Ext.emptyFn,
	setHeight:Ext.emptyFn,
	setPosition:Ext.emptyFn,
	setPagePosition:Ext.emptyFn,
	markInvalid:Ext.emptyFn,
	clearInvalid:Ext.emptyFn});
Ext.reg('hidden',Ext.form.Hidden);
Ext.form.BasicForm=function(el,config){
	Ext.apply(this,config);
	if(Ext.isString(this.paramOrder)){
		this.paramOrder=this.paramOrder.split(/[\s,|]/);
	}
	this.items=new Ext.util.MixedCollection(false,function(o){
		return o.itemId||o.id||(o.id=Ext.id());
	});
	this.addEvents(
		'beforeaction',
		'actionfailed',
		'actioncomplete'
	);
	if(el){
		this.initEl(el);
	}
	Ext.form.BasicForm.superclass.constructor.call(this);};
Ext.extend(Ext.form.BasicForm,Ext.util.Observable,{
	timeout:30,
	paramOrder:undefined,
	paramsAsHash:false,
	activeAction:null,
	trackResetOnLoad:false,
	initEl:function(el){
		this.el=Ext.get(el);
		this.id=this.el.id||Ext.id();
		if(!this.standardSubmit){
			this.el.on('submit',this.onSubmit,this);
		}
		this.el.addClass('x-form');
	},
	getEl:function(){
		return this.el;
	},
	onSubmit:function(e){
		e.stopEvent();
	},
	destroy:function(){
		this.items.each(function(f){
			Ext.destroy(f);
		});
		if(this.el){
			this.el.removeAllListeners();
			this.el.remove();
		}
		this.purgeListeners();
	},
	isValid:function(){
		var valid=true;
		this.items.each(function(f){
		 if(!f.validate()){
			 valid=false;
		}
		});
		return valid;
	},
	isDirty:function(){
		var dirty=false;
		this.items.each(function(f){
		 if(f.isDirty()){
			 dirty=true;
			 return false;
		}
		});
		return dirty;
	},
	doAction:function(action,options){
		if(Ext.isString(action)){
			action=new Ext.form.Action.ACTION_TYPES[action](this,options);
		}
		if(this.fireEvent('beforeaction',this,action)!==false){
			this.beforeAction(action);
			action.run.defer(100,action);
		}
		return this;
	},
	submit:function(options){
		if(this.standardSubmit){
			var v=this.isValid();
			if(v){
				this.el.dom.submit();
			}
			return v;
		}
		var submitAction=String.format('{0}submit',this.api?'direct':'');
		this.doAction(submitAction,options);
		return this;
	},
	load:function(options){
		var loadAction=String.format('{0}load',this.api?'direct':'');
		this.doAction(loadAction,options);
		return this;
	},
	updateRecord:function(record){
		record.beginEdit();
		var fs=record.fields;
		fs.each(function(f){
			var field=this.findField(f.name);
			if(field){
				record.set(f.name,field.getValue());
			}
		},this);
		record.endEdit();
		return this;
	},
	loadRecord:function(record){
		this.setValues(record.data);
		return this;
	},
	beforeAction:function(action){
		var o=action.options;
		if(o.waitMsg){
			if(this.waitMsgTarget===true){
				this.el.mask(o.waitMsg,'x-mask-loading');
			}else if(this.waitMsgTarget){
				this.waitMsgTarget=Ext.get(this.waitMsgTarget);
				this.waitMsgTarget.mask(o.waitMsg,'x-mask-loading');
			}else{
				Ext.MessageBox.wait(o.waitMsg,o.waitTitle||this.waitTitle||'Please Wait...');
			}
		}
	},
	afterAction:function(action,success){
		this.activeAction=null;
		var o=action.options;
		if(o.waitMsg){
			if(this.waitMsgTarget===true){
				this.el.unmask();
			}else if(this.waitMsgTarget){
				this.waitMsgTarget.unmask();
			}else{
				Ext.MessageBox.updateProgress(1);
				Ext.MessageBox.hide();
			}
		}
		if(success){
			if(o.reset){
				this.reset();
			}
			Ext.callback(o.success,o.scope,[this,action]);
			this.fireEvent('actioncomplete',this,action);
		}else{
			Ext.callback(o.failure,o.scope,[this,action]);
			this.fireEvent('actionfailed',this,action);
		}
	},
	findField:function(id){
		var field=this.items.get(id);
		if(!Ext.isObject(field)){
			this.items.each(function(f){
				if(f.isFormField&&(f.dataIndex==id||f.id==id||f.getName()==id)){
					field=f;
					return false;
				}
			});
		}
		return field||null;
	},
	markInvalid:function(errors){
		if(Ext.isArray(errors)){
			for(var i=0,len=errors.length;i<len;i++){
				var fieldError=errors[i];
				var f=this.findField(fieldError.id);
				if(f){
					f.markInvalid(fieldError.msg);
				}
			}
		}else{
			var field,id;
			for(id in errors){
				if(!Ext.isFunction(errors[id])&&(field=this.findField(id))){
					field.markInvalid(errors[id]);
				}
			}
		}
		return this;
	},
	setValues:function(values){
		if(Ext.isArray(values)){
			for(var i=0,len=values.length;i<len;i++){
				var v=values[i];
				var f=this.findField(v.id);
				if(f){
					f.setValue(v.value);
					if(this.trackResetOnLoad){
						f.originalValue=f.getValue();
					}
				}
			}
		}else{
			var field,id;
			for(id in values){
				if(!Ext.isFunction(values[id])&&(field=this.findField(id))){
					field.setValue(values[id]);
					if(this.trackResetOnLoad){
						field.originalValue=field.getValue();
					}
				}
			}
		}
		return this;
	},
	getValues:function(asString){
		var fs=Ext.lib.Ajax.serializeForm(this.el.dom);
		if(asString===true){
			return fs;
		}
		return Ext.urlDecode(fs);
	},
	getFieldValues:function(){
		var o={};
		this.items.each(function(f){
		 o[f.getName()]=f.getValue();
		});
		return o;
	},
	clearInvalid:function(){
		this.items.each(function(f){
		 f.clearInvalid();
		});
		return this;
	},
	reset:function(){
		this.items.each(function(f){
			f.reset();
		});
		return this;
	},
	add:function(){
		this.items.addAll(Array.prototype.slice.call(arguments,0));
		return this;
	},
	remove:function(field){
		this.items.remove(field);
		return this;
	},
	render:function(){
		this.items.each(function(f){
			if(f.isFormField&&!f.rendered&&document.getElementById(f.id)){
				f.applyToMarkup(f.id);
			}
		});
		return this;
	},
	applyToFields:function(o){
		this.items.each(function(f){
		 Ext.apply(f,o);
		});
		return this;
	},
	applyIfToFields:function(o){
		this.items.each(function(f){
		 Ext.applyIf(f,o);
		});
		return this;
	},
	callFieldMethod:function(fnName,args){
		args=args||[];
		this.items.each(function(f){
			if(Ext.isFunction(f[fnName])){
				f[fnName].apply(f,args);
			}
		});
		return this;
	}});
Ext.BasicForm=Ext.form.BasicForm;
Ext.FormPanel=Ext.extend(Ext.Panel,{
	minButtonWidth:75,
	labelAlign:'left',
	monitorValid:false,
	monitorPoll:200,
	layout:'form',
	initComponent:function(){
		this.form=this.createForm();
		Ext.FormPanel.superclass.initComponent.call(this);
		this.bodyCfg={
			tag:'form',
			cls:this.baseCls+'-body',
			method:this.method||'POST',
			id:this.formId||Ext.id()
		};
		if(this.fileUpload){
			this.bodyCfg.enctype='multipart/form-data';
		}
		this.initItems();
		this.addEvents(
			'clientvalidation'
		);
		this.relayEvents(this.form,['beforeaction','actionfailed','actioncomplete']);
	},
	createForm:function(){
		var config=Ext.applyIf({listeners:{}},this.initialConfig);
		return new Ext.form.BasicForm(null,config);
	},
	initFields:function(){
		var f=this.form;
		var formPanel=this;
		var fn=function(c){
			if(formPanel.isField(c)){
				f.add(c);
			}if(c.isFieldWrap){
				Ext.applyIf(c,{
					labelAlign:c.ownerCt.labelAlign,
					labelWidth:c.ownerCt.labelWidth,
					itemCls:c.ownerCt.itemCls
				});
				f.add(c.field);
			}else if(c.doLayout&&c!=formPanel){
				Ext.applyIf(c,{
					labelAlign:c.ownerCt.labelAlign,
					labelWidth:c.ownerCt.labelWidth,
					itemCls:c.ownerCt.itemCls
				});
				if(c.items&&c.items.each){
					c.items.each(fn,this);
				}
			}
		};
		this.items.each(fn,this);
	},
	getLayoutTarget:function(){
		return this.form.el;
	},
	getForm:function(){
		return this.form;
	},
	onRender:function(ct,position){
		this.initFields();
		Ext.FormPanel.superclass.onRender.call(this,ct,position);
		this.form.initEl(this.body);
	},
	beforeDestroy:function(){
		this.stopMonitoring();
		Ext.FormPanel.superclass.beforeDestroy.call(this);
		this.form.items.clear();
		Ext.destroy(this.form);
	},
	isField:function(c){
		return!!c.setValue&&!!c.getValue&&!!c.markInvalid&&!!c.clearInvalid;
	},
	initEvents:function(){
		Ext.FormPanel.superclass.initEvents.call(this);
		this.on('remove',this.onRemove,this);
		this.on('add',this.onAdd,this);
		if(this.monitorValid){
			this.startMonitoring();
		}
	},
	onAdd:function(ct,c){
		if(this.isField(c)){
			this.form.add(c);
		}else if(c.findBy){
			Ext.applyIf(c,{
				labelAlign:c.ownerCt.labelAlign,
				labelWidth:c.ownerCt.labelWidth,
				itemCls:c.ownerCt.itemCls
			});
			this.form.add.apply(this.form,c.findBy(this.isField));
		}
	},
	onRemove:function(ct,c){
		if(this.isField(c)){
			Ext.destroy(c.container.up('.x-form-item'));
			this.form.remove(c);
		}else if(c.findByType){
			Ext.each(c.findBy(this.isField),this.form.remove,this.form);
		}
	},
	startMonitoring:function(){
		if(!this.validTask){
			this.validTask=new Ext.util.TaskRunner();
			this.validTask.start({
				run:this.bindHandler,
				interval:this.monitorPoll||200,
				scope:this
			});
		}
	},
	stopMonitoring:function(){
		if(this.validTask){
			this.validTask.stopAll();
			this.validTask=null;
		}
	},
	load:function(){
		this.form.load.apply(this.form,arguments);
	},
	onDisable:function(){
		Ext.FormPanel.superclass.onDisable.call(this);
		if(this.form){
			this.form.items.each(function(){
				 this.disable();
			});
		}
	},
	onEnable:function(){
		Ext.FormPanel.superclass.onEnable.call(this);
		if(this.form){
			this.form.items.each(function(){
				 this.enable();
			});
		}
	},
	bindHandler:function(){
		var valid=true;
		this.form.items.each(function(f){
			if(!f.isValid(true)){
				valid=false;
				return false;
			}
		});
		if(this.fbar){
			var fitems=this.fbar.items.items;
			for(var i=0,len=fitems.length;i<len;i++){
				var btn=fitems[i];
				if(btn.formBind===true&&btn.disabled===valid){
					btn.setDisabled(!valid);
				}
			}
		}
		this.fireEvent('clientvalidation',this,valid);
	}});
Ext.reg('form',Ext.FormPanel);
Ext.form.FormPanel=Ext.FormPanel;
Ext.form.FieldSet=Ext.extend(Ext.Panel,{
	baseCls:'x-fieldset',
	layout:'form',
	animCollapse:false,
	onRender:function(ct,position){
		if(!this.el){
			this.el=document.createElement('fieldset');
			this.el.id=this.id;
			if(this.title||this.header||this.checkboxToggle){
				this.el.appendChild(document.createElement('legend')).className='x-fieldset-header';
			}
		}
		Ext.form.FieldSet.superclass.onRender.call(this,ct,position);
		if(this.checkboxToggle){
			var o=typeof this.checkboxToggle=='object'?
					this.checkboxToggle:
					{tag:'input',type:'checkbox',name:this.checkboxName||this.id+'-checkbox'};
			this.checkbox=this.header.insertFirst(o);
			this.checkbox.dom.checked=!this.collapsed;
			this.mon(this.checkbox,'click',this.onCheckClick,this);
		}
	},
	onCollapse:function(doAnim,animArg){
		if(this.checkbox){
			this.checkbox.dom.checked=false;
		}
		Ext.form.FieldSet.superclass.onCollapse.call(this,doAnim,animArg);
	},
	onExpand:function(doAnim,animArg){
		if(this.checkbox){
			this.checkbox.dom.checked=true;
		}
		Ext.form.FieldSet.superclass.onExpand.call(this,doAnim,animArg);
	},
	onCheckClick:function(){
		this[this.checkbox.dom.checked?'expand':'collapse']();
	}
	});
Ext.reg('fieldset',Ext.form.FieldSet);
Ext.form.HtmlEditor=Ext.extend(Ext.form.Field,{
	enableFormat:true,
	enableFontSize:true,
	enableColors:true,
	enableAlignments:true,
	enableLists:true,
	enableSourceEdit:true,
	enableLinks:true,
	enableFont:true,
	createLinkText:'Please enter the URL for the link:',
	defaultLinkValue:'http:/'+'/',
	fontFamilies:[
		'Arial',
		'Courier New',
		'Tahoma',
		'Times New Roman',
		'Verdana'
	],
	defaultFont:'tahoma',
	defaultValue:(Ext.isOpera||Ext.isIE6)?'&nbsp;':'&#8203;',
	actionMode:'wrap',
	validationEvent:false,
	deferHeight:true,
	initialized:false,
	activated:false,
	sourceEditMode:false,
	onFocus:Ext.emptyFn,
	iframePad:3,
	hideMode:'offsets',
	defaultAutoCreate:{
		tag:"textarea",
		style:"width:500px;height:300px;",
		autocomplete:"off"
	},
	initComponent:function(){
		this.addEvents(
			'initialize',
			'activate',
			'beforesync',
			'beforepush',
			'sync',
			'push',
			'editmodechange'
		)
	},
	createFontOptions:function(){
		var buf=[],fs=this.fontFamilies,ff,lc;
		for(var i=0,len=fs.length;i<len;i++){
			ff=fs[i];
			lc=ff.toLowerCase();
			buf.push(
				'<option value="',lc,'" style="font-family:',ff,';"',
					(this.defaultFont==lc?' selected="true">':'>'),
					ff,
				'</option>'
			);
		}
		return buf.join('');
	},
	createToolbar:function(editor){
		var tipsEnabled=Ext.QuickTips&&Ext.QuickTips.isEnabled();
		function btn(id,toggle,handler){
			return{
				itemId:id,
				cls:'x-btn-icon',
				iconCls:'x-edit-'+id,
				enableToggle:toggle!==false,
				scope:editor,
				handler:handler||editor.relayBtnCmd,
				clickEvent:'mousedown',
				tooltip:tipsEnabled?editor.buttonTips[id]||undefined:undefined,
				overflowText:editor.buttonTips[id].title||undefined,
				tabIndex:-1
			};
		}
		var tb=new Ext.Toolbar({
			renderTo:this.wrap.dom.firstChild
		});
		this.mon(tb.el,'click',function(e){
			e.preventDefault();
		});
		if(this.enableFont&&!Ext.isSafari2){
			this.fontSelect=tb.el.createChild({
				tag:'select',
				cls:'x-font-select',
				html:this.createFontOptions()
			});
			this.mon(this.fontSelect,'change',function(){
				var font=this.fontSelect.dom.value;
				this.relayCmd('fontname',font);
				this.deferFocus();
			},this);
			tb.add(
				this.fontSelect.dom,
				'-'
			);
		}
		if(this.enableFormat){
			tb.add(
				btn('bold'),
				btn('italic'),
				btn('underline')
			);
		}
		if(this.enableFontSize){
			tb.add(
				'-',
				btn('increasefontsize',false,this.adjustFont),
				btn('decreasefontsize',false,this.adjustFont)
			);
		}
		if(this.enableColors){
			tb.add(
				'-',{
					itemId:'forecolor',
					cls:'x-btn-icon',
					iconCls:'x-edit-forecolor',
					clickEvent:'mousedown',
					tooltip:tipsEnabled?editor.buttonTips.forecolor||undefined:undefined,
					tabIndex:-1,
					menu:new Ext.menu.ColorMenu({
						allowReselect:true,
						focus:Ext.emptyFn,
						value:'000000',
						plain:true,
						listeners:{
							scope:this,
							select:function(cp,color){
								this.execCmd('forecolor',Ext.isWebKit||Ext.isIE?'#'+color:color);
								this.deferFocus();
							}
						},
						clickEvent:'mousedown'
					})
				},{
					itemId:'backcolor',
					cls:'x-btn-icon',
					iconCls:'x-edit-backcolor',
					clickEvent:'mousedown',
					tooltip:tipsEnabled?editor.buttonTips.backcolor||undefined:undefined,
					tabIndex:-1,
					menu:new Ext.menu.ColorMenu({
						focus:Ext.emptyFn,
						value:'FFFFFF',
						plain:true,
						allowReselect:true,
						listeners:{
							scope:this,
							select:function(cp,color){
								if(Ext.isGecko){
									this.execCmd('useCSS',false);
									this.execCmd('hilitecolor',color);
									this.execCmd('useCSS',true);
									this.deferFocus();
								}else{
									this.execCmd(Ext.isOpera?'hilitecolor':'backcolor',Ext.isWebKit||Ext.isIE?'#'+color:color);
									this.deferFocus();
								}
							}
						},
						clickEvent:'mousedown'
					})
				}
			);
		}
		if(this.enableAlignments){
			tb.add(
				'-',
				btn('justifyleft'),
				btn('justifycenter'),
				btn('justifyright')
			);
		}
		if(!Ext.isSafari2){
			if(this.enableLinks){
				tb.add(
					'-',
					btn('createlink',false,this.createLink)
				);
			}
			if(this.enableLists){
				tb.add(
					'-',
					btn('insertorderedlist'),
					btn('insertunorderedlist')
				);
			}
			if(this.enableSourceEdit){
				tb.add(
					'-',
					btn('sourceedit',true,function(btn){
						this.toggleSourceEdit(!this.sourceEditMode);
					})
				);
			}
		}
		this.tb=tb;
	},
	getDocMarkup:function(){
		return'<html><head><style type="text/css">body{border:0;margin:0;padding:3px;height:98%;cursor:text;}</style></head><body></body></html>';
	},
	getEditorBody:function(){
		return this.doc.body||this.doc.documentElement;
	},
	getDoc:function(){
		return Ext.isIE?this.getWin().document:(this.iframe.contentDocument||this.getWin().document);
	},
	getWin:function(){
		return Ext.isIE?this.iframe.contentWindow:window.frames[this.iframe.name];
	},
	onRender:function(ct,position){
		Ext.form.HtmlEditor.superclass.onRender.call(this,ct,position);
		this.el.dom.style.border='0 none';
		this.el.dom.setAttribute('tabIndex',-1);
		this.el.addClass('x-hidden');
		if(Ext.isIE){
			this.el.applyStyles('margin-top:-1px;margin-bottom:-1px;')
		}
		this.wrap=this.el.wrap({
			cls:'x-html-editor-wrap',cn:{cls:'x-html-editor-tb'}
		});
		this.createToolbar(this);
		this.disableItems(true);
		this.createIFrame();
		if(!this.width){
			var sz=this.el.getSize();
			this.setSize(sz.width,this.height||sz.height);
		}
	},
	createIFrame:function(){
		var iframe=document.createElement('iframe');
		iframe.name=Ext.id();
		iframe.frameBorder='0';
		iframe.src=Ext.isIE?Ext.SSL_SECURE_URL:"javascript:;";
		this.wrap.dom.appendChild(iframe);
		this.iframe=iframe;
		this.monitorTask=Ext.TaskMgr.start({
			run:this.checkDesignMode,
			scope:this,
			interval:100
		});
	},
	initFrame:function(){
		Ext.TaskMgr.stop(this.monitorTask);
		this.doc=this.getDoc();
		this.win=this.getWin();
		this.doc.open();
		this.doc.write(this.getDocMarkup());
		this.doc.close();
		var task={
			run:function(){
				if(this.doc.body||this.doc.readyState=='complete'){
					Ext.TaskMgr.stop(task);
					this.doc.designMode="on";
					this.initEditor.defer(10,this);
				}
			},
			interval:10,
			duration:10000,
			scope:this
		};
		Ext.TaskMgr.start(task);
	},
	checkDesignMode:function(){
		if(this.wrap&&this.wrap.dom.offsetWidth){
			var doc=this.getDoc();
			if(!doc){
				return;
			}
			if(!doc.editorInitialized||String(doc.designMode).toLowerCase()!='on'){
				this.initFrame();
			}
		}
	},
	disableItems:function(disabled){
		if(this.fontSelect){
			this.fontSelect.dom.disabled=disabled;
		}
		this.tb.items.each(function(item){
			if(item.itemId!='sourceedit'){
				item.setDisabled(disabled);
			}
		});
	},
	onResize:function(w,h){
		Ext.form.HtmlEditor.superclass.onResize.apply(this,arguments);
		if(this.el&&this.iframe){
			if(typeof w=='number'){
				var aw=w-this.wrap.getFrameWidth('lr');
				this.el.setWidth(this.adjustWidth('textarea',aw));
				this.tb.setWidth(aw);
				this.iframe.style.width=Math.max(aw,0)+'px';
			}
			if(typeof h=='number'){
				var ah=h-this.wrap.getFrameWidth('tb')-this.tb.el.getHeight();
				this.el.setHeight(this.adjustWidth('textarea',ah));
				this.iframe.style.height=Math.max(ah,0)+'px';
				if(this.doc){
					this.getEditorBody().style.height=Math.max((ah-(this.iframePad*2)),0)+'px';
				}
			}
		}
	},
	toggleSourceEdit:function(sourceEditMode){
		if(sourceEditMode===undefined){
			sourceEditMode=!this.sourceEditMode;
		}
		this.sourceEditMode=sourceEditMode===true;
		var btn=this.tb.items.get('sourceedit');
		if(btn.pressed!==this.sourceEditMode){
			btn.toggle(this.sourceEditMode);
			if(!btn.xtbHidden){
				return;
			}
		}
		if(this.sourceEditMode){
			this.disableItems(true);
			this.syncValue();
			this.iframe.className='x-hidden';
			this.el.removeClass('x-hidden');
			this.el.dom.removeAttribute('tabIndex');
			this.el.focus();
		}else{
			if(this.initialized){
				this.disableItems(false);
			}
			this.pushValue();
			this.iframe.className='';
			this.el.addClass('x-hidden');
			this.el.dom.setAttribute('tabIndex',-1);
			this.deferFocus();
		}
		var lastSize=this.lastSize;
		if(lastSize){
			delete this.lastSize;
			this.setSize(lastSize);
		}
		this.fireEvent('editmodechange',this,this.sourceEditMode);
	},
	createLink:function(){
		var url=prompt(this.createLinkText,this.defaultLinkValue);
		if(url&&url!='http:/'+'/'){
			this.relayCmd('createlink',url);
		}
	},
	adjustSize:Ext.BoxComponent.prototype.adjustSize,
	getResizeEl:function(){
		return this.wrap;
	},
	getPositionEl:function(){
		return this.wrap;
	},
	initEvents:function(){
		this.originalValue=this.getValue();
	},
	markInvalid:Ext.emptyFn,
	clearInvalid:Ext.emptyFn,
	setValue:function(v){
		Ext.form.HtmlEditor.superclass.setValue.call(this,v);
		this.pushValue();
		return this;
	},
	cleanHtml:function(html){
		html=String(html);
		if(html.length>5){
			if(Ext.isWebKit){
				html=html.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi,'');
			}
		}
		if(html==this.defaultValue){
			html='';
		}
		return html;
	},
	syncValue:function(){
		if(this.initialized){
			var bd=this.getEditorBody();
			var html=bd.innerHTML;
			if(Ext.isWebKit){
				var bs=bd.getAttribute('style');
				var m=bs.match(/text-align:(.*?);/i);
				if(m&&m[1]){
					html='<div style="'+m[0]+'">'+html+'</div>';
				}
			}
			html=this.cleanHtml(html);
			if(this.fireEvent('beforesync',this,html)!==false){
				this.el.dom.value=html;
				this.fireEvent('sync',this,html);
			}
		}
	},
	getValue:function(){
		this[this.sourceEditMode?'pushValue':'syncValue']();
		return Ext.form.HtmlEditor.superclass.getValue.call(this);
	},
	pushValue:function(){
		if(this.initialized){
			var v=this.el.dom.value;
			if(!this.activated&&v.length<1){
				v=this.defaultValue;
			}
			if(this.fireEvent('beforepush',this,v)!==false){
				this.getEditorBody().innerHTML=v;
				if(Ext.isGecko){
					var d=this.doc,
						mode=d.designMode.toLowerCase();
					d.designMode=mode.toggle('on','off');
					d.designMode=mode;
				}
				this.fireEvent('push',this,v);
			}
		}
	},
	deferFocus:function(){
		this.focus.defer(10,this);
	},
	focus:function(){
		if(this.win&&!this.sourceEditMode){
			this.win.focus();
		}else{
			this.el.focus();
		}
	},
	initEditor:function(){
		try{
			var dbody=this.getEditorBody();
			var ss=this.el.getStyles('font-size','font-family','background-image','background-repeat');
			ss['background-attachment']='fixed';
			dbody.bgProperties='fixed';
			Ext.DomHelper.applyStyles(dbody,ss);
			if(this.doc){
				try{
					Ext.EventManager.removeAll(this.doc);
				}catch(e){}
			}
			this.doc=this.getDoc();
			Ext.EventManager.on(this.doc,{
				'mousedown':this.onEditorEvent,
				'dblclick':this.onEditorEvent,
				'click':this.onEditorEvent,
				'keyup':this.onEditorEvent,
				buffer:100,
				scope:this
			});
			if(Ext.isGecko){
				Ext.EventManager.on(this.doc,'keypress',this.applyCommand,this);
			}
			if(Ext.isIE||Ext.isWebKit||Ext.isOpera){
				Ext.EventManager.on(this.doc,'keydown',this.fixKeys,this);
			}
			this.initialized=true;
			this.fireEvent('initialize',this);
			this.doc.editorInitialized=true;
			this.pushValue();
		}catch(e){}
	},
	onDestroy:function(){
		if(this.monitorTask){
			Ext.TaskMgr.stop(this.monitorTask);
		}
		if(this.rendered){
			Ext.destroy(this.tb);
			if(this.wrap){
				this.wrap.dom.innerHTML='';
				this.wrap.remove();
			}
		}
		if(this.el){
			this.el.removeAllListeners();
			this.el.remove();
		}
		if(this.doc){
			try{
				Ext.EventManager.removeAll(this.doc);
				for(var prop in this.doc){
				 delete this.doc[prop];
				}
			}catch(e){}
		}
		this.purgeListeners();
	},
	onFirstFocus:function(){
		this.activated=true;
		this.disableItems(false);
		if(Ext.isGecko){
			this.win.focus();
			var s=this.win.getSelection();
			if(!s.focusNode||s.focusNode.nodeType!=3){
				var r=s.getRangeAt(0);
				r.selectNodeContents(this.getEditorBody());
				r.collapse(true);
				this.deferFocus();
			}
			try{
				this.execCmd('useCSS',true);
				this.execCmd('styleWithCSS',false);
			}catch(e){}
		}
		this.fireEvent('activate',this);
	},
	adjustFont:function(btn){
		var adjust=btn.itemId=='increasefontsize'?1:-1;
		var v=parseInt(this.doc.queryCommandValue('FontSize')||2,10);
		if((Ext.isSafari&&!Ext.isSafari2)||Ext.isChrome||Ext.isAir){
			if(v<=10){
				v=1+adjust;
			}else if(v<=13){
				v=2+adjust;
			}else if(v<=16){
				v=3+adjust;
			}else if(v<=18){
				v=4+adjust;
			}else if(v<=24){
				v=5+adjust;
			}else{
				v=6+adjust;
			}
			v=v.constrain(1,6);
		}else{
			if(Ext.isSafari){
				adjust*=2;
			}
			v=Math.max(1,v+adjust)+(Ext.isSafari?'px':0);
		}
		this.execCmd('FontSize',v);
	},
	onEditorEvent:function(e){
		this.updateToolbar();
	},
	updateToolbar:function(){
		if(!this.activated){
			this.onFirstFocus();
			return;
		}
		var btns=this.tb.items.map,doc=this.doc;
		if(this.enableFont&&!Ext.isSafari2){
			var name=(this.doc.queryCommandValue('FontName')||this.defaultFont).toLowerCase();
			if(name!=this.fontSelect.dom.value){
				this.fontSelect.dom.value=name;
			}
		}
		if(this.enableFormat){
			btns.bold.toggle(doc.queryCommandState('bold'));
			btns.italic.toggle(doc.queryCommandState('italic'));
			btns.underline.toggle(doc.queryCommandState('underline'));
		}
		if(this.enableAlignments){
			btns.justifyleft.toggle(doc.queryCommandState('justifyleft'));
			btns.justifycenter.toggle(doc.queryCommandState('justifycenter'));
			btns.justifyright.toggle(doc.queryCommandState('justifyright'));
		}
		if(!Ext.isSafari2&&this.enableLists){
			btns.insertorderedlist.toggle(doc.queryCommandState('insertorderedlist'));
			btns.insertunorderedlist.toggle(doc.queryCommandState('insertunorderedlist'));
		}
		Ext.menu.MenuMgr.hideAll();
		this.syncValue();
	},
	relayBtnCmd:function(btn){
		this.relayCmd(btn.itemId);
	},
	relayCmd:function(cmd,value){
		(function(){
			this.focus();
			this.execCmd(cmd,value);
			this.updateToolbar();
		}).defer(10,this);
	},
	execCmd:function(cmd,value){
		this.doc.execCommand(cmd,false,value===undefined?null:value);
		this.syncValue();
	},
	applyCommand:function(e){
		if(e.ctrlKey){
			var c=e.getCharCode(),cmd;
			if(c>0){
				c=String.fromCharCode(c);
				switch(c){
					case'b':
						cmd='bold';
					break;
					case'i':
						cmd='italic';
					break;
					case'u':
						cmd='underline';
					break;
				}
				if(cmd){
					this.win.focus();
					this.execCmd(cmd);
					this.deferFocus();
					e.preventDefault();
				}
			}
		}
	},
	insertAtCursor:function(text){
		if(!this.activated){
			return;
		}
		if(Ext.isIE){
			this.win.focus();
			var r=this.doc.selection.createRange();
			if(r){
				r.collapse(true);
				r.pasteHTML(text);
				this.syncValue();
				this.deferFocus();
			}
		}else if(Ext.isGecko||Ext.isOpera){
			this.win.focus();
			this.execCmd('InsertHTML',text);
			this.deferFocus();
		}else if(Ext.isWebKit){
			this.execCmd('InsertText',text);
			this.deferFocus();
		}
	},
	fixKeys:function(){
		if(Ext.isIE){
			return function(e){
				var k=e.getKey(),r;
				if(k==e.TAB){
					e.stopEvent();
					r=this.doc.selection.createRange();
					if(r){
						r.collapse(true);
						r.pasteHTML('&nbsp;&nbsp;&nbsp;&nbsp;');
						this.deferFocus();
					}
				}else if(k==e.ENTER){
					r=this.doc.selection.createRange();
					if(r){
						var target=r.parentElement();
						if(!target||target.tagName.toLowerCase()!='li'){
							e.stopEvent();
							r.pasteHTML('<br />');
							r.collapse(false);
							r.select();
						}
					}
				}
			};
		}else if(Ext.isOpera){
			return function(e){
				var k=e.getKey();
				if(k==e.TAB){
					e.stopEvent();
					this.win.focus();
					this.execCmd('InsertHTML','&nbsp;&nbsp;&nbsp;&nbsp;');
					this.deferFocus();
				}
			};
		}else if(Ext.isWebKit){
			return function(e){
				var k=e.getKey();
				if(k==e.TAB){
					e.stopEvent();
					this.execCmd('InsertText','\t');
					this.deferFocus();
				}
			};
		}
	}(),
	getToolbar:function(){
		return this.tb;
	},
	buttonTips:{
		bold:{
			title:'Bold (Ctrl+B)',
			text:'Make the selected text bold.',
			cls:'x-html-editor-tip'
		},
		italic:{
			title:'Italic (Ctrl+I)',
			text:'Make the selected text italic.',
			cls:'x-html-editor-tip'
		},
		underline:{
			title:'Underline (Ctrl+U)',
			text:'Underline the selected text.',
			cls:'x-html-editor-tip'
		},
		increasefontsize:{
			title:'Grow Text',
			text:'Increase the font size.',
			cls:'x-html-editor-tip'
		},
		decreasefontsize:{
			title:'Shrink Text',
			text:'Decrease the font size.',
			cls:'x-html-editor-tip'
		},
		backcolor:{
			title:'Text Highlight Color',
			text:'Change the background color of the selected text.',
			cls:'x-html-editor-tip'
		},
		forecolor:{
			title:'Font Color',
			text:'Change the color of the selected text.',
			cls:'x-html-editor-tip'
		},
		justifyleft:{
			title:'Align Text Left',
			text:'Align text to the left.',
			cls:'x-html-editor-tip'
		},
		justifycenter:{
			title:'Center Text',
			text:'Center text in the editor.',
			cls:'x-html-editor-tip'
		},
		justifyright:{
			title:'Align Text Right',
			text:'Align text to the right.',
			cls:'x-html-editor-tip'
		},
		insertunorderedlist:{
			title:'Bullet List',
			text:'Start a bulleted list.',
			cls:'x-html-editor-tip'
		},
		insertorderedlist:{
			title:'Numbered List',
			text:'Start a numbered list.',
			cls:'x-html-editor-tip'
		},
		createlink:{
			title:'Hyperlink',
			text:'Make the selected text a hyperlink.',
			cls:'x-html-editor-tip'
		},
		sourceedit:{
			title:'Source Edit',
			text:'Switch to source editing mode.',
			cls:'x-html-editor-tip'
		}
	}
	});
Ext.reg('htmleditor',Ext.form.HtmlEditor);
Ext.form.TimeField=Ext.extend(Ext.form.ComboBox,{
	minValue:null,
	maxValue:null,
	minText:"The time in this field must be equal to or after {0}",
	maxText:"The time in this field must be equal to or before {0}",
	invalidText:"{0} is not a valid time",
	format:"g:i A",
	altFormats:"g:ia|g:iA|g:i a|g:i A|h:i|g:i|H:i|ga|ha|gA|h a|g a|g A|gi|hi|gia|hia|g|H",
	increment:15,
	mode:'local',
	triggerAction:'all',
	typeAhead:false,
	initDate:'1/1/2008',
	initComponent:function(){
		if(typeof this.minValue=="string"){
			this.minValue=this.parseDate(this.minValue);
		}
		if(typeof this.maxValue=="string"){
			this.maxValue=this.parseDate(this.maxValue);
		}
		if(!this.store){
			var min=this.parseDate(this.minValue)||new Date(this.initDate).clearTime();
			var max=this.parseDate(this.maxValue)||new Date(this.initDate).clearTime().add('mi',(24*60)-1);
			var times=[];
			while(min<=max){
				times.push(min.dateFormat(this.format));
				min=min.add('mi',this.increment);
			}
			this.store=times;
		}
		Ext.form.TimeField.superclass.initComponent.call(this);
	},
	getValue:function(){
		var v=Ext.form.TimeField.superclass.getValue.call(this);
		return this.formatDate(this.parseDate(v))||'';
	},
	setValue:function(value){
		return Ext.form.TimeField.superclass.setValue.call(this,this.formatDate(this.parseDate(value)));
	},
	validateValue:Ext.form.DateField.prototype.validateValue,
	parseDate:Ext.form.DateField.prototype.parseDate,
	formatDate:Ext.form.DateField.prototype.formatDate,
	beforeBlur:function(){
		var v=this.parseDate(this.getRawValue());
		if(v){
			this.setValue(v.dateFormat(this.format));
		}
		Ext.form.TimeField.superclass.beforeBlur.call(this);
	}
	});
Ext.reg('timefield',Ext.form.TimeField);
Ext.form.Label=Ext.extend(Ext.BoxComponent,{
	onRender:function(ct,position){
		if(!this.el){
			this.el=document.createElement('label');
			this.el.id=this.getId();
			this.el.innerHTML=this.text?Ext.util.Format.htmlEncode(this.text):(this.html||'');
			if(this.forId){
				this.el.setAttribute('for',this.forId);
			}
		}
		Ext.form.Label.superclass.onRender.call(this,ct,position);
	},
	setText:function(t,encode){
		var e=encode===false;
		this[!e?'text':'html']=t;
		delete this[e?'text':'html'];
		if(this.rendered){
			this.el.dom.innerHTML=encode!==false?Ext.util.Format.htmlEncode(t):t;
		}
		return this;
	}});
Ext.reg('label',Ext.form.Label);
Ext.form.Action=function(form,options){
	this.form=form;
	this.options=options||{};};
Ext.form.Action.CLIENT_INVALID='client';
Ext.form.Action.SERVER_INVALID='server';
Ext.form.Action.CONNECT_FAILURE='connect';
Ext.form.Action.LOAD_FAILURE='load';
Ext.form.Action.prototype={
	type:'default',
	run:function(options){
	},
	success:function(response){
	},
	handleResponse:function(response){
	},
	failure:function(response){
		this.response=response;
		this.failureType=Ext.form.Action.CONNECT_FAILURE;
		this.form.afterAction(this,false);
	},
	processResponse:function(response){
		this.response=response;
		if(!response.responseText&&!response.responseXML){
			return true;
		}
		this.result=this.handleResponse(response);
		return this.result;
	},
	getUrl:function(appendParams){
		var url=this.options.url||this.form.url||this.form.el.dom.action;
		if(appendParams){
			var p=this.getParams();
			if(p){
				url=Ext.urlAppend(url,p);
			}
		}
		return url;
	},
	getMethod:function(){
		return(this.options.method||this.form.method||this.form.el.dom.method||'POST').toUpperCase();
	},
	getParams:function(){
		var bp=this.form.baseParams;
		var p=this.options.params;
		if(p){
			if(typeof p=="object"){
				p=Ext.urlEncode(Ext.applyIf(p,bp));
			}else if(typeof p=='string'&&bp){
				p+='&'+Ext.urlEncode(bp);
			}
		}else if(bp){
			p=Ext.urlEncode(bp);
		}
		return p;
	},
	createCallback:function(opts){
		var opts=opts||{};
		return{
			success:this.success,
			failure:this.failure,
			scope:this,
			timeout:(opts.timeout*1000)||(this.form.timeout*1000),
			upload:this.form.fileUpload?this.success:undefined
		};
	}};
Ext.form.Action.Submit=function(form,options){
	Ext.form.Action.Submit.superclass.constructor.call(this,form,options);};
Ext.extend(Ext.form.Action.Submit,Ext.form.Action,{
	type:'submit',
	run:function(){
		var o=this.options;
		var method=this.getMethod();
		var isGet=method=='GET';
		if(o.clientValidation===false||this.form.isValid()){
			Ext.Ajax.request(Ext.apply(this.createCallback(o),{
				form:this.form.el.dom,
				url:this.getUrl(isGet),
				method:method,
				headers:o.headers,
				params:!isGet?this.getParams():null,
				isUpload:this.form.fileUpload
			}));
		}else if(o.clientValidation!==false){
			this.failureType=Ext.form.Action.CLIENT_INVALID;
			this.form.afterAction(this,false);
		}
	},
	success:function(response){
		var result=this.processResponse(response);
		if(result===true||result.success){
			this.form.afterAction(this,true);
			return;
		}
		if(result.errors){
			this.form.markInvalid(result.errors);
			this.failureType=Ext.form.Action.SERVER_INVALID;
		}
		this.form.afterAction(this,false);
	},
	handleResponse:function(response){
		if(this.form.errorReader){
			var rs=this.form.errorReader.read(response);
			var errors=[];
			if(rs.records){
				for(var i=0,len=rs.records.length;i<len;i++){
					var r=rs.records[i];
					errors[i]=r.data;
				}
			}
			if(errors.length<1){
				errors=null;
			}
			return{
				success:rs.success,
				errors:errors
			};
		}
		return Ext.decode(response.responseText);
	}});
Ext.form.Action.Load=function(form,options){
	Ext.form.Action.Load.superclass.constructor.call(this,form,options);
	this.reader=this.form.reader;};
Ext.extend(Ext.form.Action.Load,Ext.form.Action,{
	type:'load',
	run:function(){
		Ext.Ajax.request(Ext.apply(
				this.createCallback(this.options),{
					method:this.getMethod(),
					url:this.getUrl(false),
					headers:this.options.headers,
					params:this.getParams()
		}));
	},
	success:function(response){
		var result=this.processResponse(response);
		if(result===true||!result.success||!result.data){
			this.failureType=Ext.form.Action.LOAD_FAILURE;
			this.form.afterAction(this,false);
			return;
		}
		this.form.clearInvalid();
		this.form.setValues(result.data);
		this.form.afterAction(this,true);
	},
	handleResponse:function(response){
		if(this.form.reader){
			var rs=this.form.reader.read(response);
			var data=rs.records&&rs.records[0]?rs.records[0].data:null;
			return{
				success:rs.success,
				data:data
			};
		}
		return Ext.decode(response.responseText);
	}});
Ext.form.Action.DirectLoad=Ext.extend(Ext.form.Action.Load,{
	constructor:function(form,opts){
		Ext.form.Action.DirectLoad.superclass.constructor.call(this,form,opts);
	},
	type:'directload',
	run:function(){
		var args=this.getParams();
		args.push(this.success,this);
		this.form.api.load.apply(window,args);
	},
	getParams:function(){
		var buf=[],o={};
		var bp=this.form.baseParams;
		var p=this.options.params;
		Ext.apply(o,p,bp);
		var paramOrder=this.form.paramOrder;
		if(paramOrder){
			for(var i=0,len=paramOrder.length;i<len;i++){
				buf.push(o[paramOrder[i]]);
			}
		}else if(this.form.paramsAsHash){
			buf.push(o);
		}
		return buf;
	},
	processResponse:function(result){
		this.result=result;
		return result;
	}});
Ext.form.Action.DirectSubmit=Ext.extend(Ext.form.Action.Submit,{
	constructor:function(form,opts){
		Ext.form.Action.DirectSubmit.superclass.constructor.call(this,form,opts);
	},
	type:'directsubmit',
	run:function(){
		var o=this.options;
		if(o.clientValidation===false||this.form.isValid()){
			this.success.params=this.getParams();
			this.form.api.submit(this.form.el.dom,this.success,this);
		}else if(o.clientValidation!==false){
			this.failureType=Ext.form.Action.CLIENT_INVALID;
			this.form.afterAction(this,false);
		}
	},
	getParams:function(){
		var o={};
		var bp=this.form.baseParams;
		var p=this.options.params;
		Ext.apply(o,p,bp);
		return o;
	},
	processResponse:function(result){
		this.result=result;
		return result;
	}});
Ext.form.Action.ACTION_TYPES={
	'load':Ext.form.Action.Load,
	'submit':Ext.form.Action.Submit,
	'directload':Ext.form.Action.DirectLoad,
	'directsubmit':Ext.form.Action.DirectSubmit};
Ext.form.VTypes=function(){
	var alpha=/^[a-zA-Z_]+$/;
	var alphanum=/^[a-zA-Z0-9_]+$/;
	var email=/^(\w+)([-+.][\w]+)*@(\w[-\w]*\.){1,5}([A-Za-z]){2,4}$/;
	var url=/(((https?)|(ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
	return{
		'email':function(v){
			return email.test(v);
		},
		'emailText':'This field should be an e-mail address in the format "user@example.com"',
		'emailMask':/[a-z0-9_\.\-@]/i,
		'url':function(v){
			return url.test(v);
		},
		'urlText':'This field should be a URL in the format "http:/'+'/www.example.com"',
		'alpha':function(v){
			return alpha.test(v);
		},
		'alphaText':'This field should only contain letters and _',
		'alphaMask':/[a-z_]/i,
		'alphanum':function(v){
			return alphanum.test(v);
		},
		'alphanumText':'This field should only contain letters, numbers and _',
		'alphanumMask':/[a-z0-9_]/i
	};}();
Ext.grid.GridPanel=Ext.extend(Ext.Panel,{
	autoExpandColumn:false,
	autoExpandMax:1000,
	autoExpandMin:50,
	columnLines:false,
	ddText:'{0} selected row{1}',
	deferRowRender:true,
	enableColumnHide:true,
	enableColumnMove:true,
	enableDragDrop:false,
	enableHdMenu:true,
	loadMask:false,
	minColumnWidth:25,
	stripeRows:false,
	trackMouseOver:true,
	stateEvents:['columnmove','columnresize','sortchange'],
	view:null,
	rendered:false,
	viewReady:false,
	initComponent:function(){
		Ext.grid.GridPanel.superclass.initComponent.call(this);
		if(this.columnLines){
			this.cls=(this.cls||'')+' x-grid-with-col-lines';
		}
		this.autoScroll=false;
		this.autoWidth=false;
		if(Ext.isArray(this.columns)){
			this.colModel=new Ext.grid.ColumnModel(this.columns);
			delete this.columns;
		}
		if(this.ds){
			this.store=this.ds;
			delete this.ds;
		}
		if(this.cm){
			this.colModel=this.cm;
			delete this.cm;
		}
		if(this.sm){
			this.selModel=this.sm;
			delete this.sm;
		}
		this.store=Ext.StoreMgr.lookup(this.store);
		this.addEvents(
			'click',
			'dblclick',
			'contextmenu',
			'mousedown',
			'mouseup',
			'mouseover',
			'mouseout',
			'keypress',
			'keydown',
			'cellmousedown',
			'rowmousedown',
			'headermousedown',
			'cellclick',
			'celldblclick',
			'rowclick',
			'rowdblclick',
			'headerclick',
			'headerdblclick',
			'rowcontextmenu',
			'cellcontextmenu',
			'headercontextmenu',
			'bodyscroll',
			'columnresize',
			'columnmove',
			'sortchange',
			'reconfigure'
		);
	},
	onRender:function(ct,position){
		Ext.grid.GridPanel.superclass.onRender.apply(this,arguments);
		var c=this.body;
		this.el.addClass('x-grid-panel');
		var view=this.getView();
		view.init(this);
		this.mon(c,{
			mousedown:this.onMouseDown,
			click:this.onClick,
			dblclick:this.onDblClick,
			contextmenu:this.onContextMenu,
			keydown:this.onKeyDown,
			scope:this
		});
		this.relayEvents(c,['mousedown','mouseup','mouseover','mouseout','keypress']);
		this.getSelectionModel().init(this);
		this.view.render();
	},
	initEvents:function(){
		Ext.grid.GridPanel.superclass.initEvents.call(this);
		if(this.loadMask){
			this.loadMask=new Ext.LoadMask(this.bwrap,
					Ext.apply({store:this.store},this.loadMask));
		}
	},
	initStateEvents:function(){
		Ext.grid.GridPanel.superclass.initStateEvents.call(this);
		this.mon(this.colModel,'hiddenchange',this.saveState,this,{delay:100});
	},
	applyState:function(state){
		var cm=this.colModel;
		var cs=state.columns;
		if(cs){
			for(var i=0,len=cs.length;i<len;i++){
				var s=cs[i];
				var c=cm.getColumnById(s.id);
				if(c){
					c.hidden=s.hidden;
					c.width=s.width;
					var oldIndex=cm.getIndexById(s.id);
					if(oldIndex!=i){
						cm.moveColumn(oldIndex,i);
					}
				}
			}
		}
		if(state.sort&&this.store){
			this.store[this.store.remoteSort?'setDefaultSort':'sort'](state.sort.field,state.sort.direction);
		}
		delete state.columns;
		delete state.sort;
		Ext.grid.GridPanel.superclass.applyState.call(this,state);
	},
	getState:function(){
		var o={columns:[]};
		for(var i=0,c;(c=this.colModel.config[i]);i++){
			o.columns[i]={
				id:c.id,
				width:c.width
			};
			if(c.hidden){
				o.columns[i].hidden=true;
			}
		}
		if(this.store){
			var ss=this.store.getSortState();
			if(ss){
				o.sort=ss;
			}
		}
		return o;
	},
	afterRender:function(){
		Ext.grid.GridPanel.superclass.afterRender.call(this);
		this.view.layout();
		if(this.deferRowRender){
			this.view.afterRender.defer(10,this.view);
		}else{
			this.view.afterRender();
		}
		this.viewReady=true;
	},
	reconfigure:function(store,colModel){
		if(this.loadMask){
			this.loadMask.destroy();
			this.loadMask=new Ext.LoadMask(this.bwrap,
					Ext.apply({},{store:store},this.initialConfig.loadMask));
		}
		this.view.initData(store,colModel);
		this.store=store;
		this.colModel=colModel;
		if(this.rendered){
			this.view.refresh(true);
		}
		this.fireEvent('reconfigure',this,store,colModel);
	},
	onKeyDown:function(e){
		this.fireEvent('keydown',e);
	},
	onDestroy:function(){
		if(this.rendered){
			var c=this.body;
			c.removeAllListeners();
			c.update('');
			Ext.destroy(this.view,this.loadMask);
		}else if(this.store&&this.store.autoDestroy){
			this.store.destroy();
		}
		Ext.destroy(this.colModel,this.selModel);
		this.store=this.selModel=this.colModel=this.view=this.loadMask=null;
		Ext.grid.GridPanel.superclass.onDestroy.call(this);
	},
	processEvent:function(name,e){
		this.fireEvent(name,e);
		var t=e.getTarget();
		var v=this.view;
		var header=v.findHeaderIndex(t);
		if(header!==false){
			this.fireEvent('header'+name,this,header,e);
		}else{
			var row=v.findRowIndex(t);
			var cell=v.findCellIndex(t);
			if(row!==false){
				this.fireEvent('row'+name,this,row,e);
				if(cell!==false){
					this.fireEvent('cell'+name,this,row,cell,e);
				}
			}
		}
	},
	onClick:function(e){
		this.processEvent('click',e);
	},
	onMouseDown:function(e){
		this.processEvent('mousedown',e);
	},
	onContextMenu:function(e,t){
		this.processEvent('contextmenu',e);
	},
	onDblClick:function(e){
		this.processEvent('dblclick',e);
	},
	walkCells:function(row,col,step,fn,scope){
		var cm=this.colModel,clen=cm.getColumnCount();
		var ds=this.store,rlen=ds.getCount(),first=true;
		if(step<0){
			if(col<0){
				row--;
				first=false;
			}
			while(row>=0){
				if(!first){
					col=clen-1;
				}
				first=false;
				while(col>=0){
					if(fn.call(scope||this,row,col,cm)===true){
						return[row,col];
					}
					col--;
				}
				row--;
			}
		}else{
			if(col>=clen){
				row++;
				first=false;
			}
			while(row<rlen){
				if(!first){
					col=0;
				}
				first=false;
				while(col<clen){
					if(fn.call(scope||this,row,col,cm)===true){
						return[row,col];
					}
					col++;
				}
				row++;
			}
		}
		return null;
	},
	onResize:function(){
		Ext.grid.GridPanel.superclass.onResize.apply(this,arguments);
		if(this.viewReady){
			this.view.layout();
		}
	},
	getGridEl:function(){
		return this.body;
	},
	stopEditing:Ext.emptyFn,
	getSelectionModel:function(){
		if(!this.selModel){
			this.selModel=new Ext.grid.RowSelectionModel(
					this.disableSelection?{selectRow:Ext.emptyFn}:null);
		}
		return this.selModel;
	},
	getStore:function(){
		return this.store;
	},
	getColumnModel:function(){
		return this.colModel;
	},
	getView:function(){
		if(!this.view){
			this.view=new Ext.grid.GridView(this.viewConfig);
		}
		return this.view;
	},
	getDragDropText:function(){
		var count=this.selModel.getCount();
		return String.format(this.ddText,count,count==1?'':'s');
	}
	});
Ext.reg('grid',Ext.grid.GridPanel);
Ext.grid.GridView=function(config){
	Ext.apply(this,config);
	this.addEvents(
		"beforerowremoved",
		"beforerowsinserted",
		"beforerefresh",
		"rowremoved",
		"rowsinserted",
		"rowupdated",
		"refresh"
	);
	Ext.grid.GridView.superclass.constructor.call(this);};
Ext.extend(Ext.grid.GridView,Ext.util.Observable,{
	deferEmptyText:true,
	scrollOffset:19,
	autoFill:false,
	forceFit:false,
	sortClasses:["sort-asc","sort-desc"],
	sortAscText:"Sort Ascending",
	sortDescText:"Sort Descending",
	columnsText:"Columns",
	selectedRowClass:"x-grid3-row-selected",
	borderWidth:2,
	tdClass:'x-grid3-cell',
	hdCls:'x-grid3-hd',
	markDirty:true,
	cellSelectorDepth:4,
	rowSelectorDepth:10,
	cellSelector:'td.x-grid3-cell',
	rowSelector:'div.x-grid3-row',
	firstRowCls:'x-grid3-row-first',
	lastRowCls:'x-grid3-row-last',
	rowClsRe:/(?:^|\s+)x-grid3-row-(first|last|alt)(?:\s+|$)/g,
	initTemplates:function(){
		var ts=this.templates||{};
		if(!ts.master){
			ts.master=new Ext.Template(
					'<div class="x-grid3" hidefocus="true">',
						'<div class="x-grid3-viewport">',
							'<div class="x-grid3-header"><div class="x-grid3-header-inner"><div class="x-grid3-header-offset" style="{ostyle}">{header}</div></div><div class="x-clear"></div></div>',
							'<div class="x-grid3-scroller"><div class="x-grid3-body" style="{bstyle}">{body}</div><a href="#" class="x-grid3-focus" tabIndex="-1"></a></div>',
						'</div>',
						'<div class="x-grid3-resize-marker">&#160;</div>',
						'<div class="x-grid3-resize-proxy">&#160;</div>',
					'</div>'
					);
		}
		if(!ts.header){
			ts.header=new Ext.Template(
					'<table border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
					'<thead><tr class="x-grid3-hd-row">{cells}</tr></thead>',
					'</table>'
					);
		}
		if(!ts.hcell){
			ts.hcell=new Ext.Template(
					'<td class="x-grid3-hd x-grid3-cell x-grid3-td-{id} {css}" style="{style}"><div {tooltip} {attr} class="x-grid3-hd-inner x-grid3-hd-{id}" unselectable="on" style="{istyle}">',this.grid.enableHdMenu?'<a class="x-grid3-hd-btn" href="#"></a>':'',
					'{value}<img class="x-grid3-sort-icon" src="',Ext.BLANK_IMAGE_URL,'" />',
					'</div></td>'
					);
		}
		if(!ts.body){
			ts.body=new Ext.Template('{rows}');
		}
		if(!ts.row){
			ts.row=new Ext.Template(
					'<div class="x-grid3-row {alt}" style="{tstyle}"><table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
					'<tbody><tr>{cells}</tr>',
					(this.enableRowBody?'<tr class="x-grid3-row-body-tr" style="{bodyStyle}"><td colspan="{cols}" class="x-grid3-body-cell" tabIndex="0" hidefocus="on"><div class="x-grid3-row-body">{body}</div></td></tr>':''),
					'</tbody></table></div>'
					);
		}
		if(!ts.cell){
			ts.cell=new Ext.Template(
					'<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" style="{style}" tabIndex="0" {cellAttr}>',
					'<div class="x-grid3-cell-inner x-grid3-col-{id}" unselectable="on" {attr}>{value}</div>',
					'</td>'
					);
		}
		for(var k in ts){
			var t=ts[k];
			if(t&&typeof t.compile=='function'&&!t.compiled){
				t.disableFormats=true;
				t.compile();
			}
		}
		this.templates=ts;
		this.colRe=new RegExp("x-grid3-td-([^\\s]+)","");
	},
	fly:function(el){
		if(!this._flyweight){
			this._flyweight=new Ext.Element.Flyweight(document.body);
		}
		this._flyweight.dom=el;
		return this._flyweight;
	},
	getEditorParent:function(){
		return this.scroller.dom;
	},
	initElements:function(){
		var E=Ext.Element;
		var el=this.grid.getGridEl().dom.firstChild;
		var cs=el.childNodes;
		this.el=new E(el);
		this.mainWrap=new E(cs[0]);
		this.mainHd=new E(this.mainWrap.dom.firstChild);
		if(this.grid.hideHeaders){
			this.mainHd.setDisplayed(false);
		}
		this.innerHd=this.mainHd.dom.firstChild;
		this.scroller=new E(this.mainWrap.dom.childNodes[1]);
		if(this.forceFit){
			this.scroller.setStyle('overflow-x','hidden');
		}
		this.mainBody=new E(this.scroller.dom.firstChild);
		this.focusEl=new E(this.scroller.dom.childNodes[1]);
		this.focusEl.swallowEvent("click",true);
		this.resizeMarker=new E(cs[1]);
		this.resizeProxy=new E(cs[2]);
	},
	getRows:function(){
		return this.hasRows()?this.mainBody.dom.childNodes:[];
	},
	findCell:function(el){
		if(!el){
			return false;
		}
		return this.fly(el).findParent(this.cellSelector,this.cellSelectorDepth);
	},
	findCellIndex:function(el,requiredCls){
		var cell=this.findCell(el);
		if(cell&&(!requiredCls||this.fly(cell).hasClass(requiredCls))){
			return this.getCellIndex(cell);
		}
		return false;
	},
	getCellIndex:function(el){
		if(el){
			var m=el.className.match(this.colRe);
			if(m&&m[1]){
				return this.cm.getIndexById(m[1]);
			}
		}
		return false;
	},
	findHeaderCell:function(el){
		var cell=this.findCell(el);
		return cell&&this.fly(cell).hasClass(this.hdCls)?cell:null;
	},
	findHeaderIndex:function(el){
		return this.findCellIndex(el,this.hdCls);
	},
	findRow:function(el){
		if(!el){
			return false;
		}
		return this.fly(el).findParent(this.rowSelector,this.rowSelectorDepth);
	},
	findRowIndex:function(el){
		var r=this.findRow(el);
		return r?r.rowIndex:false;
	},
	getRow:function(row){
		return this.getRows()[row];
	},
	getCell:function(row,col){
		return this.getRow(row).getElementsByTagName('td')[col];
	},
	getHeaderCell:function(index){
	 return this.mainHd.dom.getElementsByTagName('td')[index];
	},
	addRowClass:function(row,cls){
		var r=this.getRow(row);
		if(r){
			this.fly(r).addClass(cls);
		}
	},
	removeRowClass:function(row,cls){
		var r=this.getRow(row);
		if(r){
			this.fly(r).removeClass(cls);
		}
	},
	removeRow:function(row){
		Ext.removeNode(this.getRow(row));
		this.syncFocusEl(row);
	},
	removeRows:function(firstRow,lastRow){
		var bd=this.mainBody.dom;
		for(var rowIndex=firstRow;rowIndex<=lastRow;rowIndex++){
			Ext.removeNode(bd.childNodes[firstRow]);
		}
		this.syncFocusEl(firstRow);
	},
	getScrollState:function(){
		var sb=this.scroller.dom;
		return{left:sb.scrollLeft,top:sb.scrollTop};
	},
	restoreScroll:function(state){
		var sb=this.scroller.dom;
		sb.scrollLeft=state.left;
		sb.scrollTop=state.top;
	},
	scrollToTop:function(){
		this.scroller.dom.scrollTop=0;
		this.scroller.dom.scrollLeft=0;
	},
	syncScroll:function(){
	 this.syncHeaderScroll();
	 var mb=this.scroller.dom;
		this.grid.fireEvent("bodyscroll",mb.scrollLeft,mb.scrollTop);
	},
	syncHeaderScroll:function(){
		var mb=this.scroller.dom;
		this.innerHd.scrollLeft=mb.scrollLeft;
		this.innerHd.scrollLeft=mb.scrollLeft;
	},
	updateSortIcon:function(col,dir){
		var sc=this.sortClasses;
		var hds=this.mainHd.select('td').removeClass(sc);
		hds.item(col).addClass(sc[dir=="DESC"?1:0]);
	},
	updateAllColumnWidths:function(){
		var tw=this.getTotalWidth(),
			clen=this.cm.getColumnCount(),
			ws=[],
			len,
			i;
		for(i=0;i<clen;i++){
			ws[i]=this.getColumnWidth(i);
		}
		this.innerHd.firstChild.style.width=this.getOffsetWidth();
		this.innerHd.firstChild.firstChild.style.width=tw;
		this.mainBody.dom.style.width=tw;
		for(i=0;i<clen;i++){
			var hd=this.getHeaderCell(i);
			hd.style.width=ws[i];
		}
		var ns=this.getRows(),row,trow;
		for(i=0,len=ns.length;i<len;i++){
			row=ns[i];
			row.style.width=tw;
			if(row.firstChild){
				row.firstChild.style.width=tw;
				trow=row.firstChild.rows[0];
				for(var j=0;j<clen;j++){
				 trow.childNodes[j].style.width=ws[j];
				}
			}
		}
		this.onAllColumnWidthsUpdated(ws,tw);
	},
	updateColumnWidth:function(col,width){
		var w=this.getColumnWidth(col);
		var tw=this.getTotalWidth();
		this.innerHd.firstChild.style.width=this.getOffsetWidth();
		this.innerHd.firstChild.firstChild.style.width=tw;
		this.mainBody.dom.style.width=tw;
		var hd=this.getHeaderCell(col);
		hd.style.width=w;
		var ns=this.getRows(),row;
		for(var i=0,len=ns.length;i<len;i++){
			row=ns[i];
			row.style.width=tw;
			if(row.firstChild){
				row.firstChild.style.width=tw;
				row.firstChild.rows[0].childNodes[col].style.width=w;
			}
		}
		this.onColumnWidthUpdated(col,w,tw);
	},
	updateColumnHidden:function(col,hidden){
		var tw=this.getTotalWidth();
		this.innerHd.firstChild.style.width=this.getOffsetWidth();
		this.innerHd.firstChild.firstChild.style.width=tw;
		this.mainBody.dom.style.width=tw;
		var display=hidden?'none':'';
		var hd=this.getHeaderCell(col);
		hd.style.display=display;
		var ns=this.getRows(),row;
		for(var i=0,len=ns.length;i<len;i++){
			row=ns[i];
			row.style.width=tw;
			if(row.firstChild){
				row.firstChild.style.width=tw;
				row.firstChild.rows[0].childNodes[col].style.display=display;
			}
		}
		this.onColumnHiddenUpdated(col,hidden,tw);
		delete this.lastViewWidth;
		this.layout();
	},
	doRender:function(cs,rs,ds,startRow,colCount,stripe){
		var ts=this.templates,ct=ts.cell,rt=ts.row,last=colCount-1;
		var tstyle='width:'+this.getTotalWidth()+';';
		var buf=[],cb,c,p={},rp={tstyle:tstyle},r;
		for(var j=0,len=rs.length;j<len;j++){
			r=rs[j];cb=[];
			var rowIndex=(j+startRow);
			for(var i=0;i<colCount;i++){
				c=cs[i];
				p.id=c.id;
				p.css=i===0?'x-grid3-cell-first ':(i==last?'x-grid3-cell-last ':'');
				p.attr=p.cellAttr="";
				p.value=c.renderer(r.data[c.name],p,r,rowIndex,i,ds);
				p.style=c.style;
				if(Ext.isEmpty(p.value)){
					p.value="&#160;";
				}
				if(this.markDirty&&r.dirty&&typeof r.modified[c.name]!=='undefined'){
					p.css+=' x-grid3-dirty-cell';
				}
				cb[cb.length]=ct.apply(p);
			}
			var alt=[];
			if(stripe&&((rowIndex+1)%2===0)){
				alt[0]="x-grid3-row-alt";
			}
			if(r.dirty){
				alt[1]=" x-grid3-dirty-row";
			}
			rp.cols=colCount;
			if(this.getRowClass){
				alt[2]=this.getRowClass(r,rowIndex,rp,ds);
			}
			rp.alt=alt.join(" ");
			rp.cells=cb.join("");
			buf[buf.length]=rt.apply(rp);
		}
		return buf.join("");
	},
	processRows:function(startRow,skipStripe){
		if(!this.ds||this.ds.getCount()<1){
			return;
		}
		var rows=this.getRows();
		skipStripe=skipStripe||!this.grid.stripeRows;
		startRow=startRow||0;
		Ext.each(rows,function(row,idx){
			row.rowIndex=idx;
			row.className=row.className.replace(this.rowClsRe,' ');
			if(!skipStripe&&(idx+1)%2===0){
				row.className+=' x-grid3-row-alt';
			}
		});
		if(startRow===0){
			Ext.fly(rows[0]).addClass(this.firstRowCls);
		}
		Ext.fly(rows[rows.length-1]).addClass(this.lastRowCls);
	},
	afterRender:function(){
		if(!this.ds||!this.cm){
			return;
		}
		this.mainBody.dom.innerHTML=this.renderRows()||'&#160;';
		this.processRows(0,true);
		if(this.deferEmptyText!==true){
			this.applyEmptyText();
		}
	},
	renderUI:function(){
		var header=this.renderHeaders();
		var body=this.templates.body.apply({rows:'&#160;'});
		var html=this.templates.master.apply({
			body:body,
			header:header,
			ostyle:'width:'+this.getOffsetWidth()+';',
			bstyle:'width:'+this.getTotalWidth()+';'
		});
		
		var g=this.grid;
		g.getGridEl().dom.innerHTML=html;
		this.initElements();
		Ext.fly(this.innerHd).on("click",this.handleHdDown,this);
		this.mainHd.on({
			scope:this,
			mouseover:this.handleHdOver,
			mouseout:this.handleHdOut,
			mousemove:this.handleHdMove
		});
		this.scroller.on('scroll',this.syncScroll,this);
		if(g.enableColumnResize!==false){
			this.splitZone=new Ext.grid.GridView.SplitDragZone(g,this.mainHd.dom);
		}
		if(g.enableColumnMove){
			this.columnDrag=new Ext.grid.GridView.ColumnDragZone(g,this.innerHd);
			this.columnDrop=new Ext.grid.HeaderDropZone(g,this.mainHd.dom);
		}
		if(g.enableHdMenu!==false){
			this.hmenu=new Ext.menu.Menu({id:g.id+"-hctx"});
			this.hmenu.add(
				{itemId:"asc",text:this.sortAscText,cls:"xg-hmenu-sort-asc"},
				{itemId:"desc",text:this.sortDescText,cls:"xg-hmenu-sort-desc"}
			);
			if(g.enableColumnHide!==false){
				this.colMenu=new Ext.menu.Menu({id:g.id+"-hcols-menu"});
				this.colMenu.on({
					scope:this,
					beforeshow:this.beforeColMenuShow,
					itemclick:this.handleHdMenuClick
				});
				this.hmenu.add('-',{
					itemId:"columns",
					hideOnClick:false,
					text:this.columnsText,
					menu:this.colMenu,
					iconCls:'x-cols-icon'
				});
			}
			this.hmenu.on("itemclick",this.handleHdMenuClick,this);
		}
		if(g.trackMouseOver){
			this.mainBody.on({
				scope:this,
				mouseover:this.onRowOver,
				mouseout:this.onRowOut
			});
		}
		if(g.enableDragDrop||g.enableDrag){
			this.dragZone=new Ext.grid.GridDragZone(g,{
				ddGroup:g.ddGroup||'GridDD'
			});
		}
		this.updateHeaderSortState();
	},
	layout:function(){
		if(!this.mainBody){
			return;
		}
		var g=this.grid;
		var c=g.getGridEl();
		var csize=c.getSize(true);
		var vw=csize.width;
		if(!g.hideHeaders&&(vw<20||csize.height<20)){
			return;
		}
		if(g.autoHeight){
			this.scroller.dom.style.overflow='visible';
			if(Ext.isWebKit){
				this.scroller.dom.style.position='static';
			}
		}else{
			this.el.setSize(csize.width,csize.height);
			var hdHeight=this.mainHd.getHeight();
			var vh=csize.height-(hdHeight);
			this.scroller.setSize(vw,vh);
			if(this.innerHd){
				this.innerHd.style.width=(vw)+'px';
			}
		}
		if(this.forceFit){
			if(this.lastViewWidth!=vw){
				this.fitColumns(false,false);
				this.lastViewWidth=vw;
			}
		}else{
			this.autoExpand();
			this.syncHeaderScroll();
		}
		this.onLayout(vw,vh);
	},
	onLayout:function(vw,vh){
	},
	onColumnWidthUpdated:function(col,w,tw){
	},
	onAllColumnWidthsUpdated:function(ws,tw){
	},
	onColumnHiddenUpdated:function(col,hidden,tw){
	},
	updateColumnText:function(col,text){
	},
	afterMove:function(colIndex){
	},
	init:function(grid){
		this.grid=grid;
		this.initTemplates();
		this.initData(grid.store,grid.colModel);
		this.initUI(grid);
	},
	getColumnId:function(index){
	 return this.cm.getColumnId(index);
	},
	getOffsetWidth:function(){
		return(this.cm.getTotalWidth()+this.scrollOffset)+'px';
	},
	renderHeaders:function(){
		var cm=this.cm,
			ts=this.templates,
			ct=ts.hcell,
			cb=[],
			p={},
			len=cm.getColumnCount(),
			last=len-1;
		for(var i=0;i<len;i++){
			p.id=cm.getColumnId(i);
			p.value=cm.getColumnHeader(i)||"";
			p.style=this.getColumnStyle(i,true);
			p.tooltip=this.getColumnTooltip(i);
			p.css=i===0?'x-grid3-cell-first ':(i==last?'x-grid3-cell-last ':'');
			if(cm.config[i].align=='right'){
				p.istyle='padding-right:16px';
			}else{
				delete p.istyle;
			}
			cb[cb.length]=ct.apply(p);
		}
		return ts.header.apply({cells:cb.join(""),tstyle:'width:'+this.getTotalWidth()+';'});
	},
	getColumnTooltip:function(i){
		var tt=this.cm.getColumnTooltip(i);
		if(tt){
			if(Ext.QuickTips.isEnabled()){
				return'ext:qtip="'+tt+'"';
			}else{
				return'title="'+tt+'"';
			}
		}
		return"";
	},
	beforeUpdate:function(){
		this.grid.stopEditing(true);
	},
	updateHeaders:function(){
		this.innerHd.firstChild.innerHTML=this.renderHeaders();
		this.innerHd.firstChild.style.width=this.getOffsetWidth();
		this.innerHd.firstChild.firstChild.style.width=this.getTotalWidth();
	},
	focusRow:function(row){
		this.focusCell(row,0,false);
	},
	focusCell:function(row,col,hscroll){
		this.syncFocusEl(this.ensureVisible(row,col,hscroll));
		if(Ext.isGecko){
			this.focusEl.focus();
		}else{
			this.focusEl.focus.defer(1,this.focusEl);
		}
	},
	resolveCell:function(row,col,hscroll){
		if(typeof row!="number"){
			row=row.rowIndex;
		}
		if(!this.ds){
			return null;
		}
		if(row<0||row>=this.ds.getCount()){
			return null;
		}
		col=(col!==undefined?col:0);
		var rowEl=this.getRow(row),
			cm=this.cm,
			colCount=cm.getColumnCount(),
			cellEl;
		if(!(hscroll===false&&col===0)){
			while(col<colCount&&cm.isHidden(col)){
				col++;
			}
			cellEl=this.getCell(row,col);
		}
		return{row:rowEl,cell:cellEl};
	},
	getResolvedXY:function(resolved){
		if(!resolved){
			return null;
		}
		var s=this.scroller.dom,c=resolved.cell,r=resolved.row;
		return c?Ext.fly(c).getXY():[this.el.getX(),Ext.fly(r).getY()];
	},
	syncFocusEl:function(row,col,hscroll){
		var xy=row;
		if(!Ext.isArray(xy)){
			row=Math.min(row,Math.max(0,this.getRows().length-1));
			xy=this.getResolvedXY(this.resolveCell(row,col,hscroll));
		}
		this.focusEl.setXY(xy||this.scroller.getXY());
	},
	ensureVisible:function(row,col,hscroll){
		var resolved=this.resolveCell(row,col,hscroll);
		if(!resolved||!resolved.row){
			return;
		}
		var rowEl=resolved.row,
			cellEl=resolved.cell,
			c=this.scroller.dom,
			ctop=0,
			p=rowEl,
			stop=this.el.dom;
		while(p&&p!=stop){
			ctop+=p.offsetTop;
			p=p.offsetParent;
		}
		ctop-=this.mainHd.dom.offsetHeight;
		var cbot=ctop+rowEl.offsetHeight,
			ch=c.clientHeight,
			sbot=stop+ch;
		stop=parseInt(c.scrollTop,10);
		if(ctop<stop){
		 c.scrollTop=ctop;
		}else if(cbot>sbot){
			c.scrollTop=cbot-ch;
		}
		if(hscroll!==false){
			var cleft=parseInt(cellEl.offsetLeft,10);
			var cright=cleft+cellEl.offsetWidth;
			var sleft=parseInt(c.scrollLeft,10);
			var sright=sleft+c.clientWidth;
			if(cleft<sleft){
				c.scrollLeft=cleft;
			}else if(cright>sright){
				c.scrollLeft=cright-c.clientWidth;
			}
		}
		return this.getResolvedXY(resolved);
	},
	insertRows:function(dm,firstRow,lastRow,isUpdate){
		var last=dm.getCount()-1;
		if(!isUpdate&&firstRow===0&&lastRow>=last){
			this.refresh();
		}else{
			if(!isUpdate){
				this.fireEvent("beforerowsinserted",this,firstRow,lastRow);
			}
			var html=this.renderRows(firstRow,lastRow),
				before=this.getRow(firstRow);
			if(before){
				if(firstRow===0){
					Ext.fly(this.getRow(0)).removeClass(this.firstRowCls);
				}
				Ext.DomHelper.insertHtml('beforeBegin',before,html);
			}else{
				var r=this.getRow(last-1);
				if(r){
					Ext.fly(r).removeClass(this.lastRowCls);
				}
				Ext.DomHelper.insertHtml('beforeEnd',this.mainBody.dom,html);
			}
			if(!isUpdate){
				this.fireEvent("rowsinserted",this,firstRow,lastRow);
				this.processRows(firstRow);
			}else if(firstRow===0||firstRow>=last){
				Ext.fly(this.getRow(firstRow)).addClass(firstRow===0?this.firstRowCls:this.lastRowCls);
			}
		}
		this.syncFocusEl(firstRow);
	},
	deleteRows:function(dm,firstRow,lastRow){
		if(dm.getRowCount()<1){
			this.refresh();
		}else{
			this.fireEvent("beforerowsdeleted",this,firstRow,lastRow);
			this.removeRows(firstRow,lastRow);
			this.processRows(firstRow);
			this.fireEvent("rowsdeleted",this,firstRow,lastRow);
		}
	},
	getColumnStyle:function(col,isHeader){
		var style=!isHeader?(this.cm.config[col].css||''):'';
		style+='width:'+this.getColumnWidth(col)+';';
		if(this.cm.isHidden(col)){
			style+='display:none;';
		}
		var align=this.cm.config[col].align;
		if(align){
			style+='text-align:'+align+';';
		}
		return style;
	},
	getColumnWidth:function(col){
		var w=this.cm.getColumnWidth(col);
		if(typeof w=='number'){
			return(Ext.isBorderBox?w:(w-this.borderWidth>0?w-this.borderWidth:0))+'px';
		}
		return w;
	},
	getTotalWidth:function(){
		return this.cm.getTotalWidth()+'px';
	},
	fitColumns:function(preventRefresh,onlyExpand,omitColumn){
		var cm=this.cm,i;
		var tw=cm.getTotalWidth(false);
		var aw=this.grid.getGridEl().getWidth(true)-this.scrollOffset;
		if(aw<20){
			return;
		}
		var extra=aw-tw;
		if(extra===0){
			return false;
		}
		var vc=cm.getColumnCount(true);
		var ac=vc-(typeof omitColumn=='number'?1:0);
		if(ac===0){
			ac=1;
			omitColumn=undefined;
		}
		var colCount=cm.getColumnCount();
		var cols=[];
		var extraCol=0;
		var width=0;
		var w;
		for(i=0;i<colCount;i++){
			if(!cm.isHidden(i)&&!cm.isFixed(i)&&i!==omitColumn){
				w=cm.getColumnWidth(i);
				cols.push(i);
				extraCol=i;
				cols.push(w);
				width+=w;
			}
		}
		var frac=(aw-cm.getTotalWidth())/width;
		while(cols.length){
			w=cols.pop();
			i=cols.pop();
			cm.setColumnWidth(i,Math.max(this.grid.minColumnWidth,Math.floor(w+w*frac)),true);
		}
		if((tw=cm.getTotalWidth(false))>aw){
			var adjustCol=ac!=vc?omitColumn:extraCol;
			 cm.setColumnWidth(adjustCol,Math.max(1,
					 cm.getColumnWidth(adjustCol)-(tw-aw)),true);
		}
		if(preventRefresh!==true){
			this.updateAllColumnWidths();
		}
		return true;
	},
	autoExpand:function(preventUpdate){
		var g=this.grid,cm=this.cm;
		if(!this.userResized&&g.autoExpandColumn){
			var tw=cm.getTotalWidth(false);
			var aw=this.grid.getGridEl().getWidth(true)-this.scrollOffset;
			if(tw!=aw){
				var ci=cm.getIndexById(g.autoExpandColumn);
				var currentWidth=cm.getColumnWidth(ci);
				var cw=Math.min(Math.max(((aw-tw)+currentWidth),g.autoExpandMin),g.autoExpandMax);
				if(cw!=currentWidth){
					cm.setColumnWidth(ci,cw,true);
					if(preventUpdate!==true){
						this.updateColumnWidth(ci,cw);
					}
				}
			}
		}
	},
	getColumnData:function(){
		var cs=[],cm=this.cm,colCount=cm.getColumnCount();
		for(var i=0;i<colCount;i++){
			var name=cm.getDataIndex(i);
			cs[i]={
				name:(typeof name=='undefined'?this.ds.fields.get(i).name:name),
				renderer:cm.getRenderer(i),
				id:cm.getColumnId(i),
				style:this.getColumnStyle(i)
			};
		}
		return cs;
	},
	renderRows:function(startRow,endRow){
		var g=this.grid,cm=g.colModel,ds=g.store,stripe=g.stripeRows;
		var colCount=cm.getColumnCount();
		if(ds.getCount()<1){
			return"";
		}
		var cs=this.getColumnData();
		startRow=startRow||0;
		endRow=typeof endRow=="undefined"?ds.getCount()-1:endRow;
		var rs=ds.getRange(startRow,endRow);
		return this.doRender(cs,rs,ds,startRow,colCount,stripe);
	},
	renderBody:function(){
		var markup=this.renderRows()||'&#160;';
		return this.templates.body.apply({rows:markup});
	},
	refreshRow:function(record){
		var ds=this.ds,index;
		if(typeof record=='number'){
			index=record;
			record=ds.getAt(index);
			if(!record){
				return;
			}
		}else{
			index=ds.indexOf(record);
			if(index<0){
				return;
			}
		}
		this.insertRows(ds,index,index,true);
		this.getRow(index).rowIndex=index;
		this.onRemove(ds,record,index+1,true);
		this.fireEvent("rowupdated",this,index,record);
	},
	refresh:function(headersToo){
		this.fireEvent("beforerefresh",this);
		this.grid.stopEditing(true);
		var result=this.renderBody();
		this.mainBody.update(result).setWidth(this.getTotalWidth());
		if(headersToo===true){
			this.updateHeaders();
			this.updateHeaderSortState();
		}
		this.processRows(0,true);
		this.layout();
		this.applyEmptyText();
		this.fireEvent("refresh",this);
	},
	applyEmptyText:function(){
		if(this.emptyText&&!this.hasRows()){
			this.mainBody.update('<div class="x-grid-empty">'+this.emptyText+'</div>');
		}
	},
	updateHeaderSortState:function(){
		var state=this.ds.getSortState();
		if(!state){
			return;
		}
		if(!this.sortState||(this.sortState.field!=state.field||this.sortState.direction!=state.direction)){
			this.grid.fireEvent('sortchange',this.grid,state);
		}
		this.sortState=state;
		var sortColumn=this.cm.findColumnIndex(state.field);
		if(sortColumn!=-1){
			var sortDir=state.direction;
			this.updateSortIcon(sortColumn,sortDir);
		}
	},
	destroy:function(){
		if(this.colMenu){
			Ext.menu.MenuMgr.unregister(this.colMenu);
			this.colMenu.destroy();
			delete this.colMenu;
		}
		if(this.hmenu){
			Ext.menu.MenuMgr.unregister(this.hmenu);
			this.hmenu.destroy();
			delete this.hmenu;
		}
		if(this.grid.enableColumnMove){
			var dds=Ext.dd.DDM.ids['gridHeader'+this.grid.getGridEl().id];
			if(dds){
				for(var dd in dds){
					if(!dds[dd].config.isTarget&&dds[dd].dragElId){
						var elid=dds[dd].dragElId;
						dds[dd].unreg();
						Ext.get(elid).remove();
					}else if(dds[dd].config.isTarget){
						dds[dd].proxyTop.remove();
						dds[dd].proxyBottom.remove();
						dds[dd].unreg();
					}
					if(Ext.dd.DDM.locationCache[dd]){
						delete Ext.dd.DDM.locationCache[dd];
					}
				}
				delete Ext.dd.DDM.ids['gridHeader'+this.grid.getGridEl().id];
			}
		}
		if(this.dragZone){
			this.dragZone.unreg();
		}
		Ext.fly(this.innerHd).removeAllListeners();
		Ext.removeNode(this.innerHd);
		Ext.destroy(this.resizeMarker,this.resizeProxy,this.focusEl,this.mainBody,
					this.scroller,this.mainHd,this.mainWrap,this.dragZone,
					this.splitZone,this.columnDrag,this.columnDrop);
		this.initData(null,null);
		Ext.EventManager.removeResizeListener(this.onWindowResize,this);
		this.purgeListeners();
	},
	onDenyColumnHide:function(){
	},
	render:function(){
		if(this.autoFill){
			var ct=this.grid.ownerCt;
			if(ct&&ct.getLayout()){
				ct.on('afterlayout',function(){
					this.fitColumns(true,true);
					this.updateHeaders();
				},this,{single:true});
			}else{
				this.fitColumns(true,true);
			}
		}else if(this.forceFit){
			this.fitColumns(true,false);
		}else if(this.grid.autoExpandColumn){
			this.autoExpand(true);
		}
		this.renderUI();
	},
	initData:function(ds,cm){
		if(this.ds){
			this.ds.un("load",this.onLoad,this);
			this.ds.un("datachanged",this.onDataChange,this);
			this.ds.un("add",this.onAdd,this);
			this.ds.un("remove",this.onRemove,this);
			this.ds.un("update",this.onUpdate,this);
			this.ds.un("clear",this.onClear,this);
			if(this.ds!==ds&&this.ds.autoDestroy){
				this.ds.destroy();
			}
		}
		if(ds){
			ds.on({
				scope:this,
				load:this.onLoad,
				datachanged:this.onDataChange,
				add:this.onAdd,
				remove:this.onRemove,
				update:this.onUpdate,
				clear:this.onClear
			});
		}
		this.ds=ds;
		if(this.cm){
			this.cm.un("configchange",this.onColConfigChange,this);
			this.cm.un("widthchange",this.onColWidthChange,this);
			this.cm.un("headerchange",this.onHeaderChange,this);
			this.cm.un("hiddenchange",this.onHiddenChange,this);
			this.cm.un("columnmoved",this.onColumnMove,this);
		}
		if(cm){
			delete this.lastViewWidth;
			cm.on({
				scope:this,
				configchange:this.onColConfigChange,
				widthchange:this.onColWidthChange,
				headerchange:this.onHeaderChange,
				hiddenchange:this.onHiddenChange,
				columnmoved:this.onColumnMove
			});
		}
		this.cm=cm;
	},
	onDataChange:function(){
		this.refresh();
		this.updateHeaderSortState();
		this.syncFocusEl(0);
	},
	onClear:function(){
		this.refresh();
		this.syncFocusEl(0);
	},
	onUpdate:function(ds,record){
		this.refreshRow(record);
	},
	onAdd:function(ds,records,index){
		this.insertRows(ds,index,index+(records.length-1));
	},
	onRemove:function(ds,record,index,isUpdate){
		if(isUpdate!==true){
			this.fireEvent("beforerowremoved",this,index,record);
		}
		this.removeRow(index);
		if(isUpdate!==true){
			this.processRows(index);
			this.applyEmptyText();
			this.fireEvent("rowremoved",this,index,record);
		}
	},
	onLoad:function(){
		this.scrollToTop();
	},
	onColWidthChange:function(cm,col,width){
		this.updateColumnWidth(col,width);
	},
	onHeaderChange:function(cm,col,text){
		this.updateHeaders();
	},
	onHiddenChange:function(cm,col,hidden){
		this.updateColumnHidden(col,hidden);
	},
	onColumnMove:function(cm,oldIndex,newIndex){
		this.indexMap=null;
		var s=this.getScrollState();
		this.refresh(true);
		this.restoreScroll(s);
		this.afterMove(newIndex);
		this.grid.fireEvent('columnmove',oldIndex,newIndex);
	},
	onColConfigChange:function(){
		delete this.lastViewWidth;
		this.indexMap=null;
		this.refresh(true);
	},
	initUI:function(grid){
		grid.on("headerclick",this.onHeaderClick,this);
	},
	initEvents:function(){
	},
	onHeaderClick:function(g,index){
		if(this.headersDisabled||!this.cm.isSortable(index)){
			return;
		}
		g.stopEditing(true);
		g.store.sort(this.cm.getDataIndex(index));
	},
	onRowOver:function(e,t){
		var row;
		if((row=this.findRowIndex(t))!==false){
			this.addRowClass(row,"x-grid3-row-over");
		}
	},
	onRowOut:function(e,t){
		var row;
		if((row=this.findRowIndex(t))!==false&&!e.within(this.getRow(row),true)){
			this.removeRowClass(row,"x-grid3-row-over");
		}
	},
	handleWheel:function(e){
		e.stopPropagation();
	},
	onRowSelect:function(row){
		this.addRowClass(row,this.selectedRowClass);
	},
	onRowDeselect:function(row){
		this.removeRowClass(row,this.selectedRowClass);
	},
	onCellSelect:function(row,col){
		var cell=this.getCell(row,col);
		if(cell){
			this.fly(cell).addClass("x-grid3-cell-selected");
		}
	},
	onCellDeselect:function(row,col){
		var cell=this.getCell(row,col);
		if(cell){
			this.fly(cell).removeClass("x-grid3-cell-selected");
		}
	},
	onColumnSplitterMoved:function(i,w){
		this.userResized=true;
		var cm=this.grid.colModel;
		cm.setColumnWidth(i,w,true);
		if(this.forceFit){
			this.fitColumns(true,false,i);
			this.updateAllColumnWidths();
		}else{
			this.updateColumnWidth(i,w);
			this.syncHeaderScroll();
		}
		this.grid.fireEvent("columnresize",i,w);
	},
	handleHdMenuClick:function(item){
		var index=this.hdCtxIndex;
		var cm=this.cm,ds=this.ds;
		switch(item.itemId){
			case"asc":
				ds.sort(cm.getDataIndex(index),"ASC");
				break;
			case"desc":
				ds.sort(cm.getDataIndex(index),"DESC");
				break;
			default:
				index=cm.getIndexById(item.itemId.substr(4));
				if(index!=-1){
					if(item.checked&&cm.getColumnsBy(this.isHideableColumn,this).length<=1){
						this.onDenyColumnHide();
						return false;
					}
					cm.setHidden(index,item.checked);
				}
		}
		return true;
	},
	isHideableColumn:function(c){
		return!c.hidden&&!c.fixed;
	},
	beforeColMenuShow:function(){
		var cm=this.cm,colCount=cm.getColumnCount();
		this.colMenu.removeAll();
		for(var i=0;i<colCount;i++){
			if(cm.config[i].fixed!==true&&cm.config[i].hideable!==false){
				this.colMenu.add(new Ext.menu.CheckItem({
					itemId:"col-"+cm.getColumnId(i),
					text:cm.getColumnHeader(i),
					checked:!cm.isHidden(i),
					hideOnClick:false,
					disabled:cm.config[i].hideable===false
				}));
			}
		}
	},
	handleHdDown:function(e,t){
		if(Ext.fly(t).hasClass('x-grid3-hd-btn')){
			e.stopEvent();
			var hd=this.findHeaderCell(t);
			Ext.fly(hd).addClass('x-grid3-hd-menu-open');
			var index=this.getCellIndex(hd);
			this.hdCtxIndex=index;
			var ms=this.hmenu.items,cm=this.cm;
			ms.get("asc").setDisabled(!cm.isSortable(index));
			ms.get("desc").setDisabled(!cm.isSortable(index));
			this.hmenu.on("hide",function(){
				Ext.fly(hd).removeClass('x-grid3-hd-menu-open');
			},this,{single:true});
			this.hmenu.show(t,"tl-bl?");
		}
	},
	handleHdOver:function(e,t){
		var hd=this.findHeaderCell(t);
		if(hd&&!this.headersDisabled){
			this.activeHd=hd;
			this.activeHdIndex=this.getCellIndex(hd);
			var fly=this.fly(hd);
			this.activeHdRegion=fly.getRegion();
			if(!this.cm.isMenuDisabled(this.activeHdIndex)){
				fly.addClass("x-grid3-hd-over");
				this.activeHdBtn=fly.child('.x-grid3-hd-btn');
				if(this.activeHdBtn){
					this.activeHdBtn.dom.style.height=(hd.firstChild.offsetHeight-1)+'px';
				}
			}
		}
	},
	handleHdMove:function(e,t){
		if(this.activeHd&&!this.headersDisabled){
			var hw=this.splitHandleWidth||5;
			var r=this.activeHdRegion;
			var x=e.getPageX();
			var ss=this.activeHd.style;
			if(x-r.left<=hw&&this.cm.isResizable(this.activeHdIndex-1)){
				ss.cursor=Ext.isAir?'move':Ext.isWebKit?'e-resize':'col-resize';
			}else if(r.right-x<=(!this.activeHdBtn?hw:2)&&this.cm.isResizable(this.activeHdIndex)){
				ss.cursor=Ext.isAir?'move':Ext.isWebKit?'w-resize':'col-resize';
			}else{
				ss.cursor='';
			}
		}
	},
	handleHdOut:function(e,t){
		var hd=this.findHeaderCell(t);
		if(hd&&(!Ext.isIE||!e.within(hd,true))){
			this.activeHd=null;
			this.fly(hd).removeClass("x-grid3-hd-over");
			hd.style.cursor='';
		}
	},
	hasRows:function(){
		var fc=this.mainBody.dom.firstChild;
		return fc&&fc.nodeType==1&&fc.className!='x-grid-empty';
	},
	bind:function(d,c){
		this.initData(d,c);
	}});
Ext.grid.GridView.SplitDragZone=function(grid,hd){
	this.grid=grid;
	this.view=grid.getView();
	this.marker=this.view.resizeMarker;
	this.proxy=this.view.resizeProxy;
	Ext.grid.GridView.SplitDragZone.superclass.constructor.call(this,hd,
		"gridSplitters"+this.grid.getGridEl().id,{
		dragElId:Ext.id(this.proxy.dom),resizeFrame:false
	});
	this.scroll=false;
	this.hw=this.view.splitHandleWidth||5;};
Ext.extend(Ext.grid.GridView.SplitDragZone,Ext.dd.DDProxy,{
	b4StartDrag:function(x,y){
		this.view.headersDisabled=true;
		var h=this.view.mainWrap.getHeight();
		this.marker.setHeight(h);
		this.marker.show();
		this.marker.alignTo(this.view.getHeaderCell(this.cellIndex),'tl-tl',[-2,0]);
		this.proxy.setHeight(h);
		var w=this.cm.getColumnWidth(this.cellIndex);
		var minw=Math.max(w-this.grid.minColumnWidth,0);
		this.resetConstraints();
		this.setXConstraint(minw,1000);
		this.setYConstraint(0,0);
		this.minX=x-minw;
		this.maxX=x+1000;
		this.startPos=x;
		Ext.dd.DDProxy.prototype.b4StartDrag.call(this,x,y);
	},
	handleMouseDown:function(e){
		var t=this.view.findHeaderCell(e.getTarget());
		if(t){
			var xy=this.view.fly(t).getXY(),x=xy[0],y=xy[1];
			var exy=e.getXY(),ex=exy[0];
			var w=t.offsetWidth,adjust=false;
			if((ex-x)<=this.hw){
				adjust=-1;
			}else if((x+w)-ex<=this.hw){
				adjust=0;
			}
			if(adjust!==false){
				this.cm=this.grid.colModel;
				var ci=this.view.getCellIndex(t);
				if(adjust==-1){
				 if(ci+adjust<0){
					return;
				}
					while(this.cm.isHidden(ci+adjust)){
						--adjust;
						if(ci+adjust<0){
							return;
						}
					}
				}
				this.cellIndex=ci+adjust;
				this.split=t.dom;
				if(this.cm.isResizable(this.cellIndex)&&!this.cm.isFixed(this.cellIndex)){
					Ext.grid.GridView.SplitDragZone.superclass.handleMouseDown.apply(this,arguments);
				}
			}else if(this.view.columnDrag){
				this.view.columnDrag.callHandleMouseDown(e);
			}
		}
	},
	endDrag:function(e){
		this.marker.hide();
		var v=this.view;
		var endX=Math.max(this.minX,e.getPageX());
		var diff=endX-this.startPos;
		v.onColumnSplitterMoved(this.cellIndex,this.cm.getColumnWidth(this.cellIndex)+diff);
		setTimeout(function(){
			v.headersDisabled=false;
		},50);
	},
	autoOffset:function(){
		this.setDelta(0,0);
	}});
Ext.grid.HeaderDragZone=function(grid,hd,hd2){
	this.grid=grid;
	this.view=grid.getView();
	this.ddGroup="gridHeader"+this.grid.getGridEl().id;
	Ext.grid.HeaderDragZone.superclass.constructor.call(this,hd);
	if(hd2){
		this.setHandleElId(Ext.id(hd));
		this.setOuterHandleElId(Ext.id(hd2));
	}
	this.scroll=false;};
Ext.extend(Ext.grid.HeaderDragZone,Ext.dd.DragZone,{
	maxDragWidth:120,
	getDragData:function(e){
		var t=Ext.lib.Event.getTarget(e);
		var h=this.view.findHeaderCell(t);
		if(h){
			return{ddel:h.firstChild,header:h};
		}
		return false;
	},
	onInitDrag:function(e){
		this.view.headersDisabled=true;
		var clone=this.dragData.ddel.cloneNode(true);
		clone.id=Ext.id();
		clone.style.width=Math.min(this.dragData.header.offsetWidth,this.maxDragWidth)+"px";
		this.proxy.update(clone);
		return true;
	},
	afterValidDrop:function(){
		var v=this.view;
		setTimeout(function(){
			v.headersDisabled=false;
		},50);
	},
	afterInvalidDrop:function(){
		var v=this.view;
		setTimeout(function(){
			v.headersDisabled=false;
		},50);
	}});
Ext.grid.HeaderDropZone=function(grid,hd,hd2){
	this.grid=grid;
	this.view=grid.getView();
	this.proxyTop=Ext.DomHelper.append(document.body,{
		cls:"col-move-top",html:"&#160;"
	},true);
	this.proxyBottom=Ext.DomHelper.append(document.body,{
		cls:"col-move-bottom",html:"&#160;"
	},true);
	this.proxyTop.hide=this.proxyBottom.hide=function(){
		this.setLeftTop(-100,-100);
		this.setStyle("visibility","hidden");
	};
	this.ddGroup="gridHeader"+this.grid.getGridEl().id;
	Ext.grid.HeaderDropZone.superclass.constructor.call(this,grid.getGridEl().dom);};
Ext.extend(Ext.grid.HeaderDropZone,Ext.dd.DropZone,{
	proxyOffsets:[-4,-9],
	fly:Ext.Element.fly,
	getTargetFromEvent:function(e){
		var t=Ext.lib.Event.getTarget(e);
		var cindex=this.view.findCellIndex(t);
		if(cindex!==false){
			return this.view.getHeaderCell(cindex);
		}
	},
	nextVisible:function(h){
		var v=this.view,cm=this.grid.colModel;
		h=h.nextSibling;
		while(h){
			if(!cm.isHidden(v.getCellIndex(h))){
				return h;
			}
			h=h.nextSibling;
		}
		return null;
	},
	prevVisible:function(h){
		var v=this.view,cm=this.grid.colModel;
		h=h.prevSibling;
		while(h){
			if(!cm.isHidden(v.getCellIndex(h))){
				return h;
			}
			h=h.prevSibling;
		}
		return null;
	},
	positionIndicator:function(h,n,e){
		var x=Ext.lib.Event.getPageX(e);
		var r=Ext.lib.Dom.getRegion(n.firstChild);
		var px,pt,py=r.top+this.proxyOffsets[1];
		if((r.right-x)<=(r.right-r.left)/2){
			px=r.right+this.view.borderWidth;
			pt="after";
		}else{
			px=r.left;
			pt="before";
		}
		if(this.grid.colModel.isFixed(this.view.getCellIndex(n))){
			return false;
		}
		px+=this.proxyOffsets[0];
		this.proxyTop.setLeftTop(px,py);
		this.proxyTop.show();
		if(!this.bottomOffset){
			this.bottomOffset=this.view.mainHd.getHeight();
		}
		this.proxyBottom.setLeftTop(px,py+this.proxyTop.dom.offsetHeight+this.bottomOffset);
		this.proxyBottom.show();
		return pt;
	},
	onNodeEnter:function(n,dd,e,data){
		if(data.header!=n){
			this.positionIndicator(data.header,n,e);
		}
	},
	onNodeOver:function(n,dd,e,data){
		var result=false;
		if(data.header!=n){
			result=this.positionIndicator(data.header,n,e);
		}
		if(!result){
			this.proxyTop.hide();
			this.proxyBottom.hide();
		}
		return result?this.dropAllowed:this.dropNotAllowed;
	},
	onNodeOut:function(n,dd,e,data){
		this.proxyTop.hide();
		this.proxyBottom.hide();
	},
	onNodeDrop:function(n,dd,e,data){
		var h=data.header;
		if(h!=n){
			var cm=this.grid.colModel;
			var x=Ext.lib.Event.getPageX(e);
			var r=Ext.lib.Dom.getRegion(n.firstChild);
			var pt=(r.right-x)<=((r.right-r.left)/2)?"after":"before";
			var oldIndex=this.view.getCellIndex(h);
			var newIndex=this.view.getCellIndex(n);
			if(pt=="after"){
				newIndex++;
			}
			if(oldIndex<newIndex){
				newIndex--;
			}
			cm.moveColumn(oldIndex,newIndex);
			this.grid.fireEvent("columnmove",oldIndex,newIndex);
			return true;
		}
		return false;
	}});
Ext.grid.GridView.ColumnDragZone=function(grid,hd){
	Ext.grid.GridView.ColumnDragZone.superclass.constructor.call(this,grid,hd,null);
	this.proxy.el.addClass('x-grid3-col-dd');};
Ext.extend(Ext.grid.GridView.ColumnDragZone,Ext.grid.HeaderDragZone,{
	handleMouseDown:function(e){
	},
	callHandleMouseDown:function(e){
		Ext.grid.GridView.ColumnDragZone.superclass.handleMouseDown.call(this,e);
	}});
Ext.grid.SplitDragZone=function(grid,hd,hd2){
	this.grid=grid;
	this.view=grid.getView();
	this.proxy=this.view.resizeProxy;
	Ext.grid.SplitDragZone.superclass.constructor.call(this,hd,
		"gridSplitters"+this.grid.getGridEl().id,{
		dragElId:Ext.id(this.proxy.dom),resizeFrame:false
	});
	this.setHandleElId(Ext.id(hd));
	this.setOuterHandleElId(Ext.id(hd2));
	this.scroll=false;};
Ext.extend(Ext.grid.SplitDragZone,Ext.dd.DDProxy,{
	fly:Ext.Element.fly,
	b4StartDrag:function(x,y){
		this.view.headersDisabled=true;
		this.proxy.setHeight(this.view.mainWrap.getHeight());
		var w=this.cm.getColumnWidth(this.cellIndex);
		var minw=Math.max(w-this.grid.minColumnWidth,0);
		this.resetConstraints();
		this.setXConstraint(minw,1000);
		this.setYConstraint(0,0);
		this.minX=x-minw;
		this.maxX=x+1000;
		this.startPos=x;
		Ext.dd.DDProxy.prototype.b4StartDrag.call(this,x,y);
	},
	handleMouseDown:function(e){
		var ev=Ext.EventObject.setEvent(e);
		var t=this.fly(ev.getTarget());
		if(t.hasClass("x-grid-split")){
			this.cellIndex=this.view.getCellIndex(t.dom);
			this.split=t.dom;
			this.cm=this.grid.colModel;
			if(this.cm.isResizable(this.cellIndex)&&!this.cm.isFixed(this.cellIndex)){
				Ext.grid.SplitDragZone.superclass.handleMouseDown.apply(this,arguments);
			}
		}
	},
	endDrag:function(e){
		this.view.headersDisabled=false;
		var endX=Math.max(this.minX,Ext.lib.Event.getPageX(e));
		var diff=endX-this.startPos;
		this.view.onColumnSplitterMoved(this.cellIndex,this.cm.getColumnWidth(this.cellIndex)+diff);
	},
	autoOffset:function(){
		this.setDelta(0,0);
	}});
Ext.grid.GridDragZone=function(grid,config){
	this.view=grid.getView();
	Ext.grid.GridDragZone.superclass.constructor.call(this,this.view.mainBody.dom,config);
	this.scroll=false;
	this.grid=grid;
	this.ddel=document.createElement('div');
	this.ddel.className='x-grid-dd-wrap';};
Ext.extend(Ext.grid.GridDragZone,Ext.dd.DragZone,{
	ddGroup:"GridDD",
	getDragData:function(e){
		var t=Ext.lib.Event.getTarget(e);
		var rowIndex=this.view.findRowIndex(t);
		if(rowIndex!==false){
			var sm=this.grid.selModel;
			if(!sm.isSelected(rowIndex)||e.hasModifier()){
				sm.handleMouseDown(this.grid,rowIndex,e);
			}
			return{grid:this.grid,ddel:this.ddel,rowIndex:rowIndex,selections:sm.getSelections()};
		}
		return false;
	},
	onInitDrag:function(e){
		var data=this.dragData;
		this.ddel.innerHTML=this.grid.getDragDropText();
		this.proxy.update(this.ddel);
	},
	afterRepair:function(){
		this.dragging=false;
	},
	getRepairXY:function(e,data){
		return false;
	},
	onEndDrag:function(data,e){
	},
	onValidDrop:function(dd,e,id){
		this.hideProxy();
	},
	beforeInvalidDrop:function(e,id){
	}});
Ext.grid.ColumnModel=function(config){
	if(config.columns){
		Ext.apply(this,config);
		this.setConfig(config.columns,true);
	}else{
		this.setConfig(config,true);
	}
	this.addEvents(
		"widthchange",
		"headerchange",
		"hiddenchange",
		"columnmoved",
		"configchange"
	);
	Ext.grid.ColumnModel.superclass.constructor.call(this);};
Ext.extend(Ext.grid.ColumnModel,Ext.util.Observable,{
	defaultWidth:100,
	defaultSortable:false,
	getColumnId:function(index){
		return this.config[index].id;
	},
	getColumnAt:function(index){
		return this.config[index];
	},
	setConfig:function(config,initial){
		var i,c,len;
		if(!initial){
			delete this.totalWidth;
			for(i=0,len=this.config.length;i<len;i++){
				c=this.config[i];
				if(c.editor){
					c.editor.destroy();
				}
			}
		}
		this.defaults=Ext.apply({
			width:this.defaultWidth,
			sortable:this.defaultSortable
		},this.defaults);
		this.config=config;
		this.lookup={};
		for(i=0,len=config.length;i<len;i++){
			c=Ext.applyIf(config[i],this.defaults);
			if(!c.isColumn){
				var cls=Ext.grid.Column.types[c.xtype||'gridcolumn'];
				c=new cls(c);
				config[i]=c;
			}
			this.lookup[c.id]=c;
		}
		if(!initial){
			this.fireEvent('configchange',this);
		}
	},
	getColumnById:function(id){
		return this.lookup[id];
	},
	getIndexById:function(id){
		for(var i=0,len=this.config.length;i<len;i++){
			if(this.config[i].id==id){
				return i;
			}
		}
		return-1;
	},
	moveColumn:function(oldIndex,newIndex){
		var c=this.config[oldIndex];
		this.config.splice(oldIndex,1);
		this.config.splice(newIndex,0,c);
		this.dataMap=null;
		this.fireEvent("columnmoved",this,oldIndex,newIndex);
	},
	getColumnCount:function(visibleOnly){
		if(visibleOnly===true){
			var c=0;
			for(var i=0,len=this.config.length;i<len;i++){
				if(!this.isHidden(i)){
					c++;
				}
			}
			return c;
		}
		return this.config.length;
	},
	getColumnsBy:function(fn,scope){
		var r=[];
		for(var i=0,len=this.config.length;i<len;i++){
			var c=this.config[i];
			if(fn.call(scope||this,c,i)===true){
				r[r.length]=c;
			}
		}
		return r;
	},
	isSortable:function(col){
		return this.config[col].sortable;
	},
	isMenuDisabled:function(col){
		return!!this.config[col].menuDisabled;
	},
	getRenderer:function(col){
		if(!this.config[col].renderer){
			return Ext.grid.ColumnModel.defaultRenderer;
		}
		return this.config[col].renderer;
	},
	setRenderer:function(col,fn){
		this.config[col].renderer=fn;
	},
	getColumnWidth:function(col){
		return this.config[col].width;
	},
	setColumnWidth:function(col,width,suppressEvent){
		this.config[col].width=width;
		this.totalWidth=null;
		if(!suppressEvent){
			 this.fireEvent("widthchange",this,col,width);
		}
	},
	getTotalWidth:function(includeHidden){
		if(!this.totalWidth){
			this.totalWidth=0;
			for(var i=0,len=this.config.length;i<len;i++){
				if(includeHidden||!this.isHidden(i)){
					this.totalWidth+=this.getColumnWidth(i);
				}
			}
		}
		return this.totalWidth;
	},
	getColumnHeader:function(col){
		return this.config[col].header;
	},
	setColumnHeader:function(col,header){
		this.config[col].header=header;
		this.fireEvent("headerchange",this,col,header);
	},
	getColumnTooltip:function(col){
			return this.config[col].tooltip;
	},
	setColumnTooltip:function(col,tooltip){
			this.config[col].tooltip=tooltip;
	},
	getDataIndex:function(col){
		return this.config[col].dataIndex;
	},
	setDataIndex:function(col,dataIndex){
		this.config[col].dataIndex=dataIndex;
	},
	findColumnIndex:function(dataIndex){
		var c=this.config;
		for(var i=0,len=c.length;i<len;i++){
			if(c[i].dataIndex==dataIndex){
				return i;
			}
		}
		return-1;
	},
	isCellEditable:function(colIndex,rowIndex){
		return(this.config[colIndex].editable||(typeof this.config[colIndex].editable=="undefined"&&this.config[colIndex].editor))?true:false;
	},
	getCellEditor:function(colIndex,rowIndex){
		return this.config[colIndex].getCellEditor(rowIndex);
	},
	setEditable:function(col,editable){
		this.config[col].editable=editable;
	},
	isHidden:function(colIndex){
		return this.config[colIndex].hidden;
	},
	isFixed:function(colIndex){
		return this.config[colIndex].fixed;
	},
	isResizable:function(colIndex){
		return colIndex>=0&&this.config[colIndex].resizable!==false&&this.config[colIndex].fixed!==true;
	},
	setHidden:function(colIndex,hidden){
		var c=this.config[colIndex];
		if(c.hidden!==hidden){
			c.hidden=hidden;
			this.totalWidth=null;
			this.fireEvent("hiddenchange",this,colIndex,hidden);
		}
	},
	setEditor:function(col,editor){
		Ext.destroy(this.config[col].editor);
		this.config[col].editor=editor;
	},
	destroy:function(){
		for(var i=0,c=this.config,len=c.length;i<len;i++){
			Ext.destroy(c[i].editor);
		}
		this.purgeListeners();
	}});
Ext.grid.ColumnModel.defaultRenderer=function(value){
	if(typeof value=="string"&&value.length<1){
		return"&#160;";
	}
	return value;};
Ext.grid.AbstractSelectionModel=function(){
	this.locked=false;
	Ext.grid.AbstractSelectionModel.superclass.constructor.call(this);};
Ext.extend(Ext.grid.AbstractSelectionModel,Ext.util.Observable,{
	init:function(grid){
		this.grid=grid;
		this.initEvents();
	},
	lock:function(){
		this.locked=true;
	},
	unlock:function(){
		this.locked=false;
	},
	isLocked:function(){
		return this.locked;
	},
	destroy:function(){
		this.purgeListeners();
	}});
Ext.grid.RowSelectionModel=function(config){
	Ext.apply(this,config);
	this.selections=new Ext.util.MixedCollection(false,function(o){
		return o.id;
	});
	this.last=false;
	this.lastActive=false;
	this.addEvents(
		"selectionchange",
		"beforerowselect",
		"rowselect",
		"rowdeselect"
	);
	Ext.grid.RowSelectionModel.superclass.constructor.call(this);};
Ext.extend(Ext.grid.RowSelectionModel,Ext.grid.AbstractSelectionModel,{
	singleSelect:false,
	initEvents:function(){
		if(!this.grid.enableDragDrop&&!this.grid.enableDrag){
			this.grid.on("rowmousedown",this.handleMouseDown,this);
		}else{
			this.grid.on("rowclick",function(grid,rowIndex,e){
				if(e.button===0&&!e.shiftKey&&!e.ctrlKey){
					this.selectRow(rowIndex,false);
					grid.view.focusRow(rowIndex);
				}
			},this);
		}
		this.rowNav=new Ext.KeyNav(this.grid.getGridEl(),{
			"up":function(e){
				if(!e.shiftKey||this.singleSelect){
					this.selectPrevious(false);
				}else if(this.last!==false&&this.lastActive!==false){
					var last=this.last;
					this.selectRange(this.last,this.lastActive-1);
					this.grid.getView().focusRow(this.lastActive);
					if(last!==false){
						this.last=last;
					}
				}else{
					this.selectFirstRow();
				}
			},
			"down":function(e){
				if(!e.shiftKey||this.singleSelect){
					this.selectNext(false);
				}else if(this.last!==false&&this.lastActive!==false){
					var last=this.last;
					this.selectRange(this.last,this.lastActive+1);
					this.grid.getView().focusRow(this.lastActive);
					if(last!==false){
						this.last=last;
					}
				}else{
					this.selectFirstRow();
				}
			},
			scope:this
		});
		var view=this.grid.view;
		view.on("refresh",this.onRefresh,this);
		view.on("rowupdated",this.onRowUpdated,this);
		view.on("rowremoved",this.onRemove,this);
	},
	onRefresh:function(){
		var ds=this.grid.store,index;
		var s=this.getSelections();
		this.clearSelections(true);
		for(var i=0,len=s.length;i<len;i++){
			var r=s[i];
			if((index=ds.indexOfId(r.id))!=-1){
				this.selectRow(index,true);
			}
		}
		if(s.length!=this.selections.getCount()){
			this.fireEvent("selectionchange",this);
		}
	},
	onRemove:function(v,index,r){
		if(this.selections.remove(r)!==false){
			this.fireEvent('selectionchange',this);
		}
	},
	onRowUpdated:function(v,index,r){
		if(this.isSelected(r)){
			v.onRowSelect(index);
		}
	},
	selectRecords:function(records,keepExisting){
		if(!keepExisting){
			this.clearSelections();
		}
		var ds=this.grid.store;
		for(var i=0,len=records.length;i<len;i++){
			this.selectRow(ds.indexOf(records[i]),true);
		}
	},
	getCount:function(){
		return this.selections.length;
	},
	selectFirstRow:function(){
		this.selectRow(0);
	},
	selectLastRow:function(keepExisting){
		this.selectRow(this.grid.store.getCount()-1,keepExisting);
	},
	selectNext:function(keepExisting){
		if(this.hasNext()){
			this.selectRow(this.last+1,keepExisting);
			this.grid.getView().focusRow(this.last);
			return true;
		}
		return false;
	},
	selectPrevious:function(keepExisting){
		if(this.hasPrevious()){
			this.selectRow(this.last-1,keepExisting);
			this.grid.getView().focusRow(this.last);
			return true;
		}
		return false;
	},
	hasNext:function(){
		return this.last!==false&&(this.last+1)<this.grid.store.getCount();
	},
	hasPrevious:function(){
		return!!this.last;
	},
	getSelections:function(){
		return[].concat(this.selections.items);
	},
	getSelected:function(){
		return this.selections.itemAt(0);
	},
	each:function(fn,scope){
		var s=this.getSelections();
		for(var i=0,len=s.length;i<len;i++){
			if(fn.call(scope||this,s[i],i)===false){
				return false;
			}
		}
		return true;
	},
	clearSelections:function(fast){
		if(this.isLocked()){
			return;
		}
		if(fast!==true){
			var ds=this.grid.store;
			var s=this.selections;
			s.each(function(r){
				this.deselectRow(ds.indexOfId(r.id));
			},this);
			s.clear();
		}else{
			this.selections.clear();
		}
		this.last=false;
	},
	selectAll:function(){
		if(this.isLocked()){
			return;
		}
		this.selections.clear();
		for(var i=0,len=this.grid.store.getCount();i<len;i++){
			this.selectRow(i,true);
		}
	},
	hasSelection:function(){
		return this.selections.length>0;
	},
	isSelected:function(index){
		var r=typeof index=="number"?this.grid.store.getAt(index):index;
		return(r&&this.selections.key(r.id)?true:false);
	},
	isIdSelected:function(id){
		return(this.selections.key(id)?true:false);
	},
	handleMouseDown:function(g,rowIndex,e){
		if(e.button!==0||this.isLocked()){
			return;
		}
		var view=this.grid.getView();
		if(e.shiftKey&&!this.singleSelect&&this.last!==false){
			var last=this.last;
			this.selectRange(last,rowIndex,e.ctrlKey);
			this.last=last;
			view.focusRow(rowIndex);
		}else{
			var isSelected=this.isSelected(rowIndex);
			if(e.ctrlKey&&isSelected){
				this.deselectRow(rowIndex);
			}else if(!isSelected||this.getCount()>1){
				this.selectRow(rowIndex,e.ctrlKey||e.shiftKey);
				view.focusRow(rowIndex);
			}
		}
	},
	selectRows:function(rows,keepExisting){
		if(!keepExisting){
			this.clearSelections();
		}
		for(var i=0,len=rows.length;i<len;i++){
			this.selectRow(rows[i],true);
		}
	},
	selectRange:function(startRow,endRow,keepExisting){
		var i;
		if(this.isLocked()){
			return;
		}
		if(!keepExisting){
			this.clearSelections();
		}
		if(startRow<=endRow){
			for(i=startRow;i<=endRow;i++){
				this.selectRow(i,true);
			}
		}else{
			for(i=startRow;i>=endRow;i--){
				this.selectRow(i,true);
			}
		}
	},
	deselectRange:function(startRow,endRow,preventViewNotify){
		if(this.isLocked()){
			return;
		}
		for(var i=startRow;i<=endRow;i++){
			this.deselectRow(i,preventViewNotify);
		}
	},
	selectRow:function(index,keepExisting,preventViewNotify){
		if(this.isLocked()||(index<0||index>=this.grid.store.getCount())||(keepExisting&&this.isSelected(index))){
			return;
		}
		var r=this.grid.store.getAt(index);
		if(r&&this.fireEvent("beforerowselect",this,index,keepExisting,r)!==false){
			if(!keepExisting||this.singleSelect){
				this.clearSelections();
			}
			this.selections.add(r);
			this.last=this.lastActive=index;
			if(!preventViewNotify){
				this.grid.getView().onRowSelect(index);
			}
			this.fireEvent("rowselect",this,index,r);
			this.fireEvent("selectionchange",this);
		}
	},
	deselectRow:function(index,preventViewNotify){
		if(this.isLocked()){
			return;
		}
		if(this.last==index){
			this.last=false;
		}
		if(this.lastActive==index){
			this.lastActive=false;
		}
		var r=this.grid.store.getAt(index);
		if(r){
			this.selections.remove(r);
			if(!preventViewNotify){
				this.grid.getView().onRowDeselect(index);
			}
			this.fireEvent("rowdeselect",this,index,r);
			this.fireEvent("selectionchange",this);
		}
	},
	restoreLast:function(){
		if(this._last){
			this.last=this._last;
		}
	},
	acceptsNav:function(row,col,cm){
		return!cm.isHidden(col)&&cm.isCellEditable(col,row);
	},
	onEditorKey:function(field,e){
		var k=e.getKey(),newCell,g=this.grid,ed=g.activeEditor;
		var shift=e.shiftKey;
		if(k==e.TAB){
			e.stopEvent();
			ed.completeEdit();
			if(shift){
				newCell=g.walkCells(ed.row,ed.col-1,-1,this.acceptsNav,this);
			}else{
				newCell=g.walkCells(ed.row,ed.col+1,1,this.acceptsNav,this);
			}
		}else if(k==e.ENTER){
			e.stopEvent();
			ed.completeEdit();
			if(this.moveEditorOnEnter!==false){
				if(shift){
					newCell=g.walkCells(ed.row-1,ed.col,-1,this.acceptsNav,this);
				}else{
					newCell=g.walkCells(ed.row+1,ed.col,1,this.acceptsNav,this);
				}
			}
		}else if(k==e.ESC){
			ed.cancelEdit();
		}
		if(newCell){
			g.startEditing(newCell[0],newCell[1]);
		}
	},
	destroy:function(){
		if(this.rowNav){
			this.rowNav.disable();
			this.rowNav=null;
		}
		Ext.grid.RowSelectionModel.superclass.destroy.call(this);
	}});
Ext.grid.Column=function(config){
	Ext.apply(this,config);
	if(typeof this.renderer=='string'){
		this.renderer=Ext.util.Format[this.renderer];
	}else if(Ext.isObject(this.renderer)){
		this.scope=this.renderer.scope;
		this.renderer=this.renderer.fn;
	}
	this.renderer=this.renderer.createDelegate(this.scope||config);
	if(this.id===undefined){
		this.id=++Ext.grid.Column.AUTO_ID;
	}
	if(this.editor){
		this.editor=Ext.create(this.editor,'textfield');
	}};
Ext.grid.Column.AUTO_ID=0;
Ext.grid.Column.prototype={
	isColumn:true,
	renderer:function(value){
		if(typeof value=='string'&&value.length<1){
			return'&#160;';
		}
		return value;
	},
	getEditor:function(rowIndex){
		return this.editable!==false?this.editor:null;
	},
	getCellEditor:function(rowIndex){
		var editor=this.getEditor(rowIndex);
		if(editor){
			if(!editor.startEdit){
				if(!editor.gridEditor){
					editor.gridEditor=new Ext.grid.GridEditor(editor);
				}
				return editor.gridEditor;
			}else if(editor.startEdit){
				return editor;
			}
		}
		return null;
	}};
Ext.grid.BooleanColumn=Ext.extend(Ext.grid.Column,{
	trueText:'true',
	falseText:'false',
	undefinedText:'&#160;',
	constructor:function(cfg){
		Ext.grid.BooleanColumn.superclass.constructor.call(this,cfg);
		var t=this.trueText,f=this.falseText,u=this.undefinedText;
		this.renderer=function(v){
			if(v===undefined){
				return u;
			}
			if(!v||v==='false'){
				return f;
			}
			return t;
		};
	}});
Ext.grid.NumberColumn=Ext.extend(Ext.grid.Column,{
	format:'0,000.00',
	constructor:function(cfg){
		Ext.grid.NumberColumn.superclass.constructor.call(this,cfg);
		this.renderer=Ext.util.Format.numberRenderer(this.format);
	}});
Ext.grid.DateColumn=Ext.extend(Ext.grid.Column,{
	format:'m/d/Y',
	constructor:function(cfg){
		Ext.grid.DateColumn.superclass.constructor.call(this,cfg);
		this.renderer=Ext.util.Format.dateRenderer(this.format);
	}});
Ext.grid.TemplateColumn=Ext.extend(Ext.grid.Column,{
	constructor:function(cfg){
		Ext.grid.TemplateColumn.superclass.constructor.call(this,cfg);
		var tpl=typeof Ext.isObject(this.tpl)?this.tpl:new Ext.XTemplate(this.tpl);
		this.renderer=function(value,p,r){
			return tpl.apply(r.data);
		};
		this.tpl=tpl;
	}});
Ext.grid.Column.types={
	gridcolumn:Ext.grid.Column,
	booleancolumn:Ext.grid.BooleanColumn,
	numbercolumn:Ext.grid.NumberColumn,
	datecolumn:Ext.grid.DateColumn,
	templatecolumn:Ext.grid.TemplateColumn};
Ext.grid.RowNumberer=function(config){
	Ext.apply(this,config);
	if(this.rowspan){
		this.renderer=this.renderer.createDelegate(this);
	}};
Ext.grid.RowNumberer.prototype={
	header:"",
	width:23,
	sortable:false,
	fixed:true,
	menuDisabled:true,
	dataIndex:'',
	id:'numberer',
	rowspan:undefined,
	renderer:function(v,p,record,rowIndex){
		if(this.rowspan){
			p.cellAttr='rowspan="'+this.rowspan+'"';
		}
		return rowIndex+1;
	}};
Ext.grid.CheckboxSelectionModel=Ext.extend(Ext.grid.RowSelectionModel,{
	header:'<div class="x-grid3-hd-checker">&#160;</div>',
	width:20,
	sortable:false,
	menuDisabled:true,
	fixed:true,
	dataIndex:'',
	id:'checker',
	constructor:function(){
		Ext.grid.CheckboxSelectionModel.superclass.constructor.apply(this,arguments);
		if(this.checkOnly){
			this.handleMouseDown=Ext.emptyFn;
		}
	},
	initEvents:function(){
		Ext.grid.CheckboxSelectionModel.superclass.initEvents.call(this);
		this.grid.on('render',function(){
			var view=this.grid.getView();
			view.mainBody.on('mousedown',this.onMouseDown,this);
			Ext.fly(view.innerHd).on('mousedown',this.onHdMouseDown,this);
		},this);
	},
	onMouseDown:function(e,t){
		if(e.button===0&&t.className=='x-grid3-row-checker'){
			e.stopEvent();
			var row=e.getTarget('.x-grid3-row');
			if(row){
				var index=row.rowIndex;
				if(this.isSelected(index)){
					this.deselectRow(index);
				}else{
					this.selectRow(index,true);
				}
			}
		}
	},
	onHdMouseDown:function(e,t){
		if(t.className=='x-grid3-hd-checker'){
			e.stopEvent();
			var hd=Ext.fly(t.parentNode);
			var isChecked=hd.hasClass('x-grid3-hd-checker-on');
			if(isChecked){
				hd.removeClass('x-grid3-hd-checker-on');
				this.clearSelections();
			}else{
				hd.addClass('x-grid3-hd-checker-on');
				this.selectAll();
			}
		}
	},
	renderer:function(v,p,record){
		return'<div class="x-grid3-row-checker">&#160;</div>';
	}});
Ext.grid.CellSelectionModel=function(config){
	Ext.apply(this,config);
	this.selection=null;
	this.addEvents(
		"beforecellselect",
		"cellselect",
		"selectionchange"
	);
	Ext.grid.CellSelectionModel.superclass.constructor.call(this);};
Ext.extend(Ext.grid.CellSelectionModel,Ext.grid.AbstractSelectionModel,{
	initEvents:function(){
		this.grid.on("cellmousedown",this.handleMouseDown,this);
		this.grid.getGridEl().on(Ext.EventManager.useKeydown?"keydown":"keypress",this.handleKeyDown,this);
		var view=this.grid.view;
		view.on("refresh",this.onViewChange,this);
		view.on("rowupdated",this.onRowUpdated,this);
		view.on("beforerowremoved",this.clearSelections,this);
		view.on("beforerowsinserted",this.clearSelections,this);
		if(this.grid.isEditor){
			this.grid.on("beforeedit",this.beforeEdit,this);
		}
	},
	beforeEdit:function(e){
		this.select(e.row,e.column,false,true,e.record);
	},
	onRowUpdated:function(v,index,r){
		if(this.selection&&this.selection.record==r){
			v.onCellSelect(index,this.selection.cell[1]);
		}
	},
	onViewChange:function(){
		this.clearSelections(true);
	},
	getSelectedCell:function(){
		return this.selection?this.selection.cell:null;
	},
	clearSelections:function(preventNotify){
		var s=this.selection;
		if(s){
			if(preventNotify!==true){
				this.grid.view.onCellDeselect(s.cell[0],s.cell[1]);
			}
			this.selection=null;
			this.fireEvent("selectionchange",this,null);
		}
	},
	hasSelection:function(){
		return this.selection?true:false;
	},
	handleMouseDown:function(g,row,cell,e){
		if(e.button!==0||this.isLocked()){
			return;
		}
		this.select(row,cell);
	},
	select:function(rowIndex,colIndex,preventViewNotify,preventFocus,r){
		if(this.fireEvent("beforecellselect",this,rowIndex,colIndex)!==false){
			this.clearSelections();
			r=r||this.grid.store.getAt(rowIndex);
			this.selection={
				record:r,
				cell:[rowIndex,colIndex]
			};
			if(!preventViewNotify){
				var v=this.grid.getView();
				v.onCellSelect(rowIndex,colIndex);
				if(preventFocus!==true){
					v.focusCell(rowIndex,colIndex);
				}
			}
			this.fireEvent("cellselect",this,rowIndex,colIndex);
			this.fireEvent("selectionchange",this,this.selection);
		}
	},
	isSelectable:function(rowIndex,colIndex,cm){
		return!cm.isHidden(colIndex);
	},
	handleKeyDown:function(e){
		if(!e.isNavKeyPress()){
			return;
		}
		var g=this.grid,s=this.selection;
		if(!s){
			e.stopEvent();
			var cell=g.walkCells(0,0,1,this.isSelectable,this);
			if(cell){
				this.select(cell[0],cell[1]);
			}
			return;
		}
		var sm=this;
		var walk=function(row,col,step){
			return g.walkCells(row,col,step,sm.isSelectable,sm);
		};
		var k=e.getKey(),r=s.cell[0],c=s.cell[1];
		var newCell;
		switch(k){
			 case e.TAB:
				 if(e.shiftKey){
					 newCell=walk(r,c-1,-1);
				}else{
					 newCell=walk(r,c+1,1);
				}
			 break;
			 case e.DOWN:
				 newCell=walk(r+1,c,1);
			 break;
			 case e.UP:
				 newCell=walk(r-1,c,-1);
			 break;
			 case e.RIGHT:
				 newCell=walk(r,c+1,1);
			 break;
			 case e.LEFT:
				 newCell=walk(r,c-1,-1);
			 break;
			 case e.ENTER:
				 if(g.isEditor&&!g.editing){
					g.startEditing(r,c);
					e.stopEvent();
					return;
				}
			 break;
		}
		if(newCell){
			this.select(newCell[0],newCell[1]);
			e.stopEvent();
		}
	},
	acceptsNav:function(row,col,cm){
		return!cm.isHidden(col)&&cm.isCellEditable(col,row);
	},
	onEditorKey:function(field,e){
		var k=e.getKey(),newCell,g=this.grid,ed=g.activeEditor;
		if(k==e.TAB){
			if(e.shiftKey){
				newCell=g.walkCells(ed.row,ed.col-1,-1,this.acceptsNav,this);
			}else{
				newCell=g.walkCells(ed.row,ed.col+1,1,this.acceptsNav,this);
			}
			e.stopEvent();
		}else if(k==e.ENTER){
			ed.completeEdit();
			e.stopEvent();
		}else if(k==e.ESC){
			e.stopEvent();
			ed.cancelEdit();
		}
		if(newCell){
			g.startEditing(newCell[0],newCell[1]);
		}
	}});
Ext.grid.EditorGridPanel=Ext.extend(Ext.grid.GridPanel,{
	clicksToEdit:2,
	forceValidation:false,
	isEditor:true,
	detectEdit:false,
	autoEncode:false,
	trackMouseOver:false,
	initComponent:function(){
		Ext.grid.EditorGridPanel.superclass.initComponent.call(this);
		if(!this.selModel){
			this.selModel=new Ext.grid.CellSelectionModel();
		}
		this.activeEditor=null;
		this.addEvents(
			"beforeedit",
			"afteredit",
			"validateedit"
		);
	},
	initEvents:function(){
		Ext.grid.EditorGridPanel.superclass.initEvents.call(this);
		this.on("bodyscroll",this.stopEditing,this,[true]);
		this.on("columnresize",this.stopEditing,this,[true]);
		if(this.clicksToEdit==1){
			this.on("cellclick",this.onCellDblClick,this);
		}else{
			if(this.clicksToEdit=='auto'&&this.view.mainBody){
				this.view.mainBody.on("mousedown",this.onAutoEditClick,this);
			}
			this.on("celldblclick",this.onCellDblClick,this);
		}
	},
	onCellDblClick:function(g,row,col){
		this.startEditing(row,col);
	},
	onAutoEditClick:function(e,t){
		if(e.button!==0){
			return;
		}
		var row=this.view.findRowIndex(t);
		var col=this.view.findCellIndex(t);
		if(row!==false&&col!==false){
			this.stopEditing();
			if(this.selModel.getSelectedCell){
				var sc=this.selModel.getSelectedCell();
				if(sc&&sc[0]===row&&sc[1]===col){
					this.startEditing(row,col);
				}
			}else{
				if(this.selModel.isSelected(row)){
					this.startEditing(row,col);
				}
			}
		}
	},
	onEditComplete:function(ed,value,startValue){
		this.editing=false;
		this.activeEditor=null;
		ed.un("specialkey",this.selModel.onEditorKey,this.selModel);
		var r=ed.record;
		var field=this.colModel.getDataIndex(ed.col);
		value=this.postEditValue(value,startValue,r,field);
		if(this.forceValidation===true||String(value)!==String(startValue)){
			var e={
				grid:this,
				record:r,
				field:field,
				originalValue:startValue,
				value:value,
				row:ed.row,
				column:ed.col,
				cancel:false
			};
			if(this.fireEvent("validateedit",e)!==false&&!e.cancel&&String(value)!==String(startValue)){
				r.set(field,e.value);
				delete e.cancel;
				this.fireEvent("afteredit",e);
			}
		}
		this.view.focusCell(ed.row,ed.col);
	},
	startEditing:function(row,col){
		this.stopEditing();
		if(this.colModel.isCellEditable(col,row)){
			this.view.ensureVisible(row,col,true);
			var r=this.store.getAt(row);
			var field=this.colModel.getDataIndex(col);
			var e={
				grid:this,
				record:r,
				field:field,
				value:r.data[field],
				row:row,
				column:col,
				cancel:false
			};
			if(this.fireEvent("beforeedit",e)!==false&&!e.cancel){
				this.editing=true;
				var ed=this.colModel.getCellEditor(col,row);
				if(!ed){
					return;
				}
				if(!ed.rendered){
					ed.render(this.view.getEditorParent(ed));
				}
				(function(){
					ed.row=row;
					ed.col=col;
					ed.record=r;
					ed.on("complete",this.onEditComplete,this,{single:true});
					ed.on("specialkey",this.selModel.onEditorKey,this.selModel);
					this.activeEditor=ed;
					var v=this.preEditValue(r,field);
					ed.startEdit(this.view.getCell(row,col).firstChild,v===undefined?'':v);
				}).defer(50,this);
			}
		}
	},
	preEditValue:function(r,field){
		var value=r.data[field];
		return this.autoEncode&&typeof value=='string'?Ext.util.Format.htmlDecode(value):value;
	},
	postEditValue:function(value,originalValue,r,field){
		return this.autoEncode&&typeof value=='string'?Ext.util.Format.htmlEncode(value):value;
	},
	stopEditing:function(cancel){
		if(this.activeEditor){
			this.activeEditor[cancel===true?'cancelEdit':'completeEdit']();
		}
		this.activeEditor=null;
	}});
Ext.reg('editorgrid',Ext.grid.EditorGridPanel);
Ext.grid.GridEditor=function(field,config){
	Ext.grid.GridEditor.superclass.constructor.call(this,field,config);
	field.monitorTab=false;};
Ext.extend(Ext.grid.GridEditor,Ext.Editor,{
	alignment:"tl-tl",
	autoSize:"width",
	hideEl:false,
	cls:"x-small-editor x-grid-editor",
	shim:false,
	shadow:false});
Ext.grid.PropertyRecord=Ext.data.Record.create([
	{name:'name',type:'string'},'value']);
Ext.grid.PropertyStore=function(grid,source){
	this.grid=grid;
	this.store=new Ext.data.Store({
		recordType:Ext.grid.PropertyRecord
	});
	this.store.on('update',this.onUpdate,this);
	if(source){
		this.setSource(source);
	}
	Ext.grid.PropertyStore.superclass.constructor.call(this);};
Ext.extend(Ext.grid.PropertyStore,Ext.util.Observable,{
	setSource:function(o){
		this.source=o;
		this.store.removeAll();
		var data=[];
		for(var k in o){
			if(this.isEditableValue(o[k])){
				data.push(new Ext.grid.PropertyRecord({name:k,value:o[k]},k));
			}
		}
		this.store.loadRecords({records:data},{},true);
	},
	onUpdate:function(ds,record,type){
		if(type==Ext.data.Record.EDIT){
			var v=record.data.value;
			var oldValue=record.modified.value;
			if(this.grid.fireEvent('beforepropertychange',this.source,record.id,v,oldValue)!==false){
				this.source[record.id]=v;
				record.commit();
				this.grid.fireEvent('propertychange',this.source,record.id,v,oldValue);
			}else{
				record.reject();
			}
		}
	},
	getProperty:function(row){
	 return this.store.getAt(row);
	},
	isEditableValue:function(val){
		if(Ext.isDate(val)){
			return true;
		}
		return!(Ext.isObject(val)||Ext.isFunction(val));
	},
	setValue:function(prop,value){
		this.source[prop]=value;
		this.store.getById(prop).set('value',value);
	},
	getSource:function(){
		return this.source;
	}});
Ext.grid.PropertyColumnModel=function(grid,store){
	var g=Ext.grid,
		f=Ext.form;
	this.grid=grid;
	g.PropertyColumnModel.superclass.constructor.call(this,[
		{header:this.nameText,width:50,sortable:true,dataIndex:'name',id:'name',menuDisabled:true},
		{header:this.valueText,width:50,resizable:false,dataIndex:'value',id:'value',menuDisabled:true}
	]);
	this.store=store;
	var bfield=new f.Field({
		autoCreate:{tag:'select',children:[
			{tag:'option',value:'true',html:'true'},
			{tag:'option',value:'false',html:'false'}
		]},
		getValue:function(){
			return this.el.value=='true';
		}
	});
	this.editors={
		'date':new g.GridEditor(new f.DateField({selectOnFocus:true})),
		'string':new g.GridEditor(new f.TextField({selectOnFocus:true})),
		'number':new g.GridEditor(new f.NumberField({selectOnFocus:true,style:'text-align:left;'})),
		'boolean':new g.GridEditor(bfield)
	};
	this.renderCellDelegate=this.renderCell.createDelegate(this);
	this.renderPropDelegate=this.renderProp.createDelegate(this);};
Ext.extend(Ext.grid.PropertyColumnModel,Ext.grid.ColumnModel,{
	nameText:'Name',
	valueText:'Value',
	dateFormat:'m/j/Y',
	renderDate:function(dateVal){
		return dateVal.dateFormat(this.dateFormat);
	},
	renderBool:function(bVal){
		return bVal?'true':'false';
	},
	isCellEditable:function(colIndex,rowIndex){
		return colIndex==1;
	},
	getRenderer:function(col){
		return col==1?
			this.renderCellDelegate:this.renderPropDelegate;
	},
	renderProp:function(v){
		return this.getPropertyName(v);
	},
	renderCell:function(val){
		var rv=val;
		if(Ext.isDate(val)){
			rv=this.renderDate(val);
		}else if(typeof val=='boolean'){
			rv=this.renderBool(val);
		}
		return Ext.util.Format.htmlEncode(rv);
	},
	getPropertyName:function(name){
		var pn=this.grid.propertyNames;
		return pn&&pn[name]?pn[name]:name;
	},
	getCellEditor:function(colIndex,rowIndex){
		var p=this.store.getProperty(rowIndex),
			n=p.data.name,
			val=p.data.value;
		if(this.grid.customEditors[n]){
			return this.grid.customEditors[n];
		}
		if(Ext.isDate(val)){
			return this.editors.date;
		}else if(typeof val=='number'){
			return this.editors.number;
		}else if(typeof val=='boolean'){
			return this.editors['boolean'];
		}else{
			return this.editors.string;
		}
	},
	destroy:function(){
		Ext.grid.PropertyColumnModel.superclass.destroy.call(this);
		for(var ed in this.editors){
			Ext.destroy(ed);
		}
	}});
Ext.grid.PropertyGrid=Ext.extend(Ext.grid.EditorGridPanel,{
	enableColumnMove:false,
	stripeRows:false,
	trackMouseOver:false,
	clicksToEdit:1,
	enableHdMenu:false,
	viewConfig:{
		forceFit:true
	},
	initComponent:function(){
		this.customEditors=this.customEditors||{};
		this.lastEditRow=null;
		var store=new Ext.grid.PropertyStore(this);
		this.propStore=store;
		var cm=new Ext.grid.PropertyColumnModel(this,store);
		store.store.sort('name','ASC');
		this.addEvents(
			'beforepropertychange',
			'propertychange'
		);
		this.cm=cm;
		this.ds=store.store;
		Ext.grid.PropertyGrid.superclass.initComponent.call(this);
		this.mon(this.selModel,'beforecellselect',function(sm,rowIndex,colIndex){
			if(colIndex===0){
				this.startEditing.defer(200,this,[rowIndex,1]);
				return false;
			}
		},this);
	},
	onRender:function(){
		Ext.grid.PropertyGrid.superclass.onRender.apply(this,arguments);
		this.getGridEl().addClass('x-props-grid');
	},
	afterRender:function(){
		Ext.grid.PropertyGrid.superclass.afterRender.apply(this,arguments);
		if(this.source){
			this.setSource(this.source);
		}
	},
	setSource:function(source){
		this.propStore.setSource(source);
	},
	getSource:function(){
		return this.propStore.getSource();
	}});
Ext.reg("propertygrid",Ext.grid.PropertyGrid);
Ext.grid.GroupingView=Ext.extend(Ext.grid.GridView,{
	groupByText:'Group By This Field',
	showGroupsText:'Show in Groups',
	hideGroupedColumn:false,
	showGroupName:true,
	startCollapsed:false,
	enableGrouping:true,
	enableGroupingMenu:true,
	enableNoGroups:true,
	emptyGroupText:'(None)',
	ignoreAdd:false,
	groupTextTpl:'{text}',
	gidSeed:1000,
	initTemplates:function(){
		Ext.grid.GroupingView.superclass.initTemplates.call(this);
		this.state={};
		var sm=this.grid.getSelectionModel();
		sm.on(sm.selectRow?'beforerowselect':'beforecellselect',
				this.onBeforeRowSelect,this);
		if(!this.startGroup){
			this.startGroup=new Ext.XTemplate(
				'<div id="{groupId}" class="x-grid-group {cls}">',
					'<div id="{groupId}-hd" class="x-grid-group-hd" style="{style}"><div class="x-grid-group-title">',this.groupTextTpl,'</div></div>',
					'<div id="{groupId}-bd" class="x-grid-group-body">'
			);
		}
		this.startGroup.compile();
		this.endGroup='</div></div>';
	},
	findGroup:function(el){
		return Ext.fly(el).up('.x-grid-group',this.mainBody.dom);
	},
	getGroups:function(){
		return this.hasRows()?this.mainBody.dom.childNodes:[];
	},
	onAdd:function(){
		if(this.enableGrouping&&!this.ignoreAdd){
			var ss=this.getScrollState();
			this.refresh();
			this.restoreScroll(ss);
		}else if(!this.enableGrouping){
			Ext.grid.GroupingView.superclass.onAdd.apply(this,arguments);
		}
	},
	onRemove:function(ds,record,index,isUpdate){
		Ext.grid.GroupingView.superclass.onRemove.apply(this,arguments);
		var g=document.getElementById(record._groupId);
		if(g&&g.childNodes[1].childNodes.length<1){
			Ext.removeNode(g);
		}
		this.applyEmptyText();
	},
	refreshRow:function(record){
		if(this.ds.getCount()==1){
			this.refresh();
		}else{
			this.isUpdating=true;
			Ext.grid.GroupingView.superclass.refreshRow.apply(this,arguments);
			this.isUpdating=false;
		}
	},
	beforeMenuShow:function(){
		var item,items=this.hmenu.items,disabled=this.cm.config[this.hdCtxIndex].groupable===false;
		if((item=items.get('groupBy'))){
			item.setDisabled(disabled);
		}
		if((item=items.get('showGroups'))){
			item.setDisabled(disabled);
			item.setChecked(!!this.getGroupField(),true);
		}
	},
	renderUI:function(){
		Ext.grid.GroupingView.superclass.renderUI.call(this);
		this.mainBody.on('mousedown',this.interceptMouse,this);
		if(this.enableGroupingMenu&&this.hmenu){
			this.hmenu.add('-',{
				itemId:'groupBy',
				text:this.groupByText,
				handler:this.onGroupByClick,
				scope:this,
				iconCls:'x-group-by-icon'
			});
			if(this.enableNoGroups){
				this.hmenu.add({
					itemId:'showGroups',
					text:this.showGroupsText,
					checked:true,
					checkHandler:this.onShowGroupsClick,
					scope:this
				});
			}
			this.hmenu.on('beforeshow',this.beforeMenuShow,this);
		}
	},
	onGroupByClick:function(){
		this.grid.store.groupBy(this.cm.getDataIndex(this.hdCtxIndex));
		this.beforeMenuShow();
	},
	onShowGroupsClick:function(mi,checked){
		if(checked){
			this.onGroupByClick();
		}else{
			this.grid.store.clearGrouping();
		}
	},
	toggleGroup:function(group,expanded){
		this.grid.stopEditing(true);
		group=Ext.getDom(group);
		var gel=Ext.fly(group);
		expanded=expanded!==undefined?
				expanded:gel.hasClass('x-grid-group-collapsed');
		this.state[gel.dom.id]=expanded;
		gel[expanded?'removeClass':'addClass']('x-grid-group-collapsed');
	},
	toggleAllGroups:function(expanded){
		var groups=this.getGroups();
		for(var i=0,len=groups.length;i<len;i++){
			this.toggleGroup(groups[i],expanded);
		}
	},
	expandAllGroups:function(){
		this.toggleAllGroups(true);
	},
	collapseAllGroups:function(){
		this.toggleAllGroups(false);
	},
	interceptMouse:function(e){
		var hd=e.getTarget('.x-grid-group-hd',this.mainBody);
		if(hd){
			e.stopEvent();
			this.toggleGroup(hd.parentNode);
		}
	},
	getGroup:function(v,r,groupRenderer,rowIndex,colIndex,ds){
		var g=groupRenderer?groupRenderer(v,{},r,rowIndex,colIndex,ds):String(v);
		if(g===''){
			g=this.cm.config[colIndex].emptyGroupText||this.emptyGroupText;
		}
		return g;
	},
	getGroupField:function(){
		return this.grid.store.getGroupState();
	},
	afterRender:function(){
		Ext.grid.GroupingView.superclass.afterRender.call(this);
		if(this.grid.deferRowRender){
			this.updateGroupWidths();
		}
	},
	renderRows:function(){
		var groupField=this.getGroupField();
		var eg=!!groupField;
		if(this.hideGroupedColumn){
			var colIndex=this.cm.findColumnIndex(groupField);
			if(!eg&&this.lastGroupField!==undefined){
				this.mainBody.update('');
				this.cm.setHidden(this.cm.findColumnIndex(this.lastGroupField),false);
				delete this.lastGroupField;
			}else if(eg&&this.lastGroupField===undefined){
				this.lastGroupField=groupField;
				this.cm.setHidden(colIndex,true);
			}else if(eg&&this.lastGroupField!==undefined&&groupField!==this.lastGroupField){
				this.mainBody.update('');
				var oldIndex=this.cm.findColumnIndex(this.lastGroupField);
				this.cm.setHidden(oldIndex,false);
				this.lastGroupField=groupField;
				this.cm.setHidden(colIndex,true);
			}
		}
		return Ext.grid.GroupingView.superclass.renderRows.apply(
					this,arguments);
	},
	doRender:function(cs,rs,ds,startRow,colCount,stripe){
		if(rs.length<1){
			return'';
		}
		var groupField=this.getGroupField(),
			colIndex=this.cm.findColumnIndex(groupField),
			g;
		this.enableGrouping=!!groupField;
		if(!this.enableGrouping||this.isUpdating){
			return Ext.grid.GroupingView.superclass.doRender.apply(
					this,arguments);
		}
		var gstyle='width:'+this.getTotalWidth()+';';
		var gidPrefix=this.grid.getGridEl().id;
		var cfg=this.cm.config[colIndex];
		var groupRenderer=cfg.groupRenderer||cfg.renderer;
		var prefix=this.showGroupName?
					(cfg.groupName||cfg.header)+': ':'';
		var groups=[],curGroup,i,len,gid;
		for(i=0,len=rs.length;i<len;i++){
			var rowIndex=startRow+i,
				r=rs[i],
				gvalue=r.data[groupField];
				g=this.getGroup(gvalue,r,groupRenderer,rowIndex,colIndex,ds);
			if(!curGroup||curGroup.group!=g){
				gid=gidPrefix+'-gp-'+groupField+'-'+Ext.util.Format.htmlEncode(g);
				var isCollapsed=typeof this.state[gid]!=='undefined'?!this.state[gid]:this.startCollapsed;
				var gcls=isCollapsed?'x-grid-group-collapsed':'';
				curGroup={
					group:g,
					gvalue:gvalue,
					text:prefix+g,
					groupId:gid,
					startRow:rowIndex,
					rs:[r],
					cls:gcls,
					style:gstyle
				};
				groups.push(curGroup);
			}else{
				curGroup.rs.push(r);
			}
			r._groupId=gid;
		}
		var buf=[];
		for(i=0,len=groups.length;i<len;i++){
			g=groups[i];
			this.doGroupStart(buf,g,cs,ds,colCount);
			buf[buf.length]=Ext.grid.GroupingView.superclass.doRender.call(
					this,cs,g.rs,ds,g.startRow,colCount,stripe);
			this.doGroupEnd(buf,g,cs,ds,colCount);
		}
		return buf.join('');
	},
	getGroupId:function(value){
		var gidPrefix=this.grid.getGridEl().id;
		var groupField=this.getGroupField();
		var colIndex=this.cm.findColumnIndex(groupField);
		var cfg=this.cm.config[colIndex];
		var groupRenderer=cfg.groupRenderer||cfg.renderer;
		var gtext=this.getGroup(value,{data:{}},groupRenderer,0,colIndex,this.ds);
		return gidPrefix+'-gp-'+groupField+'-'+Ext.util.Format.htmlEncode(value);
	},
	doGroupStart:function(buf,g,cs,ds,colCount){
		buf[buf.length]=this.startGroup.apply(g);
	},
	doGroupEnd:function(buf,g,cs,ds,colCount){
		buf[buf.length]=this.endGroup;
	},
	getRows:function(){
		if(!this.enableGrouping){
			return Ext.grid.GroupingView.superclass.getRows.call(this);
		}
		var r=[];
		var g,gs=this.getGroups();
		for(var i=0,len=gs.length;i<len;i++){
			g=gs[i].childNodes[1].childNodes;
			for(var j=0,jlen=g.length;j<jlen;j++){
				r[r.length]=g[j];
			}
		}
		return r;
	},
	updateGroupWidths:function(){
		if(!this.enableGrouping||!this.hasRows()){
			return;
		}
		var tw=Math.max(this.cm.getTotalWidth(),this.el.dom.offsetWidth-this.scrollOffset)+'px';
		var gs=this.getGroups();
		for(var i=0,len=gs.length;i<len;i++){
			gs[i].firstChild.style.width=tw;
		}
	},
	onColumnWidthUpdated:function(col,w,tw){
		Ext.grid.GroupingView.superclass.onColumnWidthUpdated.call(this,col,w,tw);
		this.updateGroupWidths();
	},
	onAllColumnWidthsUpdated:function(ws,tw){
		Ext.grid.GroupingView.superclass.onAllColumnWidthsUpdated.call(this,ws,tw);
		this.updateGroupWidths();
	},
	onColumnHiddenUpdated:function(col,hidden,tw){
		Ext.grid.GroupingView.superclass.onColumnHiddenUpdated.call(this,col,hidden,tw);
		this.updateGroupWidths();
	},
	onLayout:function(){
		this.updateGroupWidths();
	},
	onBeforeRowSelect:function(sm,rowIndex){
		if(!this.enableGrouping){
			return;
		}
		var row=this.getRow(rowIndex);
		if(row&&!row.offsetParent){
			var g=this.findGroup(row);
			this.toggleGroup(g,true);
		}
	}});
Ext.grid.GroupingView.GROUP_ID=1000;